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

Cleanup remaining MD5, SHA1 and Hash unit use.

Martijn Laan 11 сар өмнө
parent
commit
58b27f351b

+ 1 - 1
Examples/CodeDlg.iss

@@ -153,7 +153,7 @@ begin
     finally
     finally
       ProgressPage.Hide;
       ProgressPage.Hide;
     end;
     end;
-    if GetSHA1OfString('codedlg' + KeyPage.Values[0]) = '8013f310d340dab18a0d0cda2b5b115d2dcd97e4' then
+    if GetSHA256OfString('codedlg' + KeyPage.Values[0]) = '4c06e466ec3a2c977ac902a6cf4c602457f701b59309fc4282d9cb2234b7559b' then
       Result := True
       Result := True
     else begin
     else begin
       MsgBox('You must enter a valid registration key. (Hint: The key is "inno".)', mbError, MB_OK);
       MsgBox('You must enter a valid registration key. (Hint: The key is "inno".)', mbError, MB_OK);

+ 1 - 1
ISHelp/isetup.xml

@@ -5030,7 +5030,7 @@ DiskSliceSize=1457664
 <body>
 <body>
 <p>Specifies a password you want to prompt the user for at the beginning of the installation.</p>
 <p>Specifies a password you want to prompt the user for at the beginning of the installation.</p>
 <p>When using a password, you might consider setting <link topic="setup_encryption">Encryption</link> to <tt>yes</tt> as well, otherwise files will be stored as plain text and it would not be exceedingly difficult for someone to gain access to them through reverse engineering.</p>
 <p>When using a password, you might consider setting <link topic="setup_encryption">Encryption</link> to <tt>yes</tt> as well, otherwise files will be stored as plain text and it would not be exceedingly difficult for someone to gain access to them through reverse engineering.</p>
-<p>The password itself is not stored as clear text; it's stored as a 160-bit SHA-1 hash, salted with a 64-bit random number. (Note: When encryption is enabled, this stored hash is <i>not</i> used for the encryption key.)</p>
+<p>The password itself is not stored as clear text; it's stored as a SHA-256 hash, salted with a 64-bit random number. (Note: When encryption is enabled, this stored hash is <i>not</i> used for the encryption key.)</p>
 </body>
 </body>
 </setuptopic>
 </setuptopic>
 
 

+ 1 - 1
ISHelp/isx.xml

@@ -196,7 +196,7 @@
 <dt><tt>function <a name="CheckPassword">CheckPassword</a>(Password: String): Boolean;</tt></dt>
 <dt><tt>function <a name="CheckPassword">CheckPassword</a>(Password: String): Boolean;</tt></dt>
 <dd>
 <dd>
 <p>If Setup finds the <tt>CheckPassword</tt> event function in the Pascal script, it automatically displays the <i>Password</i> page and calls <tt>CheckPassword</tt> to check passwords. Return True to accept the password and False to reject it.</p>
 <p>If Setup finds the <tt>CheckPassword</tt> event function in the Pascal script, it automatically displays the <i>Password</i> page and calls <tt>CheckPassword</tt> to check passwords. Return True to accept the password and False to reject it.</p>
-<p>To avoid storing the actual password inside the compiled [Code] section which is stored inside Setup, you should use comparisons by hash only: calculate the SHA-1 hash of your salted password yourself and then compare that to <tt><link topic="isxfunc_GetSHA1OfString">GetSHA1OfString</link>(Password)</tt>. This way the actual value of the password remains protected.</p>
+<p>To avoid storing the actual password inside the compiled [Code] section which is stored inside Setup, you should use comparisons by hash only: calculate the SHA-256 hash of your salted password yourself and then compare that to <tt><link topic="isxfunc_GetSHA256OfString">GetSHA256OfString</link>(Password)</tt>. This way the actual value of the password is better protected.</p>
 <p>Note: If Setup is run with a /PASSWORD= <link topic="setupcmdline" anchor="PASSWORD">command line parameter</link>, your <tt>CheckPassword</tt> function will be called <i>before</i> any other event function is called, including <tt><anchorlink name="InitializeSetup">InitializeSetup</anchorlink></tt>.</p>
 <p>Note: If Setup is run with a /PASSWORD= <link topic="setupcmdline" anchor="PASSWORD">command line parameter</link>, your <tt>CheckPassword</tt> function will be called <i>before</i> any other event function is called, including <tt><anchorlink name="InitializeSetup">InitializeSetup</anchorlink></tt>.</p>
 </dd>
 </dd>
 
 

+ 9 - 9
Projects/Src/Compiler.CompressionHandler.pas

@@ -12,7 +12,7 @@ unit Compiler.CompressionHandler;
 interface
 interface
 
 
 uses
 uses
-  SHA1, ChaCha20, Shared.Int64Em, Shared.FileClass, Compression.Base,
+  SHA256, ChaCha20, Shared.Int64Em, Shared.FileClass, Compression.Base,
   Compiler.StringLists, Compiler.SetupCompiler;
   Compiler.StringLists, Compiler.SetupCompiler;
 
 
 type
 type
@@ -40,7 +40,7 @@ type
     constructor Create(ACompiler: TSetupCompiler; const InitialSliceFilename: String);
     constructor Create(ACompiler: TSetupCompiler; const InitialSliceFilename: String);
     destructor Destroy; override;
     destructor Destroy; override;
     procedure CompressFile(const SourceFile: TFile; Bytes: Integer64;
     procedure CompressFile(const SourceFile: TFile; Bytes: Integer64;
-      const CallOptimize: Boolean; var SHA1Sum: TSHA1Digest);
+      const CallOptimize: Boolean; var SHA256Sum: TSHA256Digest);
     procedure EndChunk;
     procedure EndChunk;
     procedure Finish;
     procedure Finish;
     procedure NewChunk(const ACompressorClass: TCustomCompressorClass;
     procedure NewChunk(const ACompressorClass: TCustomCompressorClass;
@@ -61,7 +61,7 @@ type
 implementation
 implementation
 
 
 uses
 uses
-  SysUtils, Hash, Shared.Struct, Compiler.Messages, Compiler.HelperFunc;
+  SysUtils, Shared.Struct, Compiler.Messages, Compiler.HelperFunc;
 
 
 constructor TCompressionHandler.Create(ACompiler: TSetupCompiler;
 constructor TCompressionHandler.Create(ACompiler: TSetupCompiler;
   const InitialSliceFilename: String);
   const InitialSliceFilename: String);
@@ -191,7 +191,7 @@ procedure TCompressionHandler.NewChunk(const ACompressorClass: TCustomCompressor
   procedure InitEncryption;
   procedure InitEncryption;
   begin
   begin
     { Create an SHA-256 hash of ACryptKey, and use that as the key }
     { Create an SHA-256 hash of ACryptKey, and use that as the key }
-    var Key := THashSHA2.GetHashBytes(ACryptKey, SHA256);
+    var Key := SHA256Buf(Pointer(ACryptKey)^, Length(ACryptKey)*SizeOf(ACryptKey[1]));
 
 
     { Create a unique nonce from the base nonce }
     { Create a unique nonce from the base nonce }
     var Nonce := FCompiler.GetEncryptionBaseNonce;
     var Nonce := FCompiler.GetEncryptionBaseNonce;
@@ -246,16 +246,16 @@ begin
 end;
 end;
 
 
 procedure TCompressionHandler.CompressFile(const SourceFile: TFile;
 procedure TCompressionHandler.CompressFile(const SourceFile: TFile;
-  Bytes: Integer64; const CallOptimize: Boolean; var SHA1Sum: TSHA1Digest);
+  Bytes: Integer64; const CallOptimize: Boolean; var SHA256Sum: TSHA256Digest);
 var
 var
-  Context: TSHA1Context;
+  Context: TSHA256Context;
   AddrOffset: LongWord;
   AddrOffset: LongWord;
   BufSize: Cardinal;
   BufSize: Cardinal;
   Buf: array[0..65535] of Byte;
   Buf: array[0..65535] of Byte;
   { ^ *must* be the same buffer size used in Setup (TFileExtractor), otherwise
   { ^ *must* be the same buffer size used in Setup (TFileExtractor), otherwise
     the TransformCallInstructions call will break }
     the TransformCallInstructions call will break }
 begin
 begin
-  SHA1Init(Context);
+  SHA256Init(Context);
   AddrOffset := 0;
   AddrOffset := 0;
   while True do begin
   while True do begin
     BufSize := SizeOf(Buf);
     BufSize := SizeOf(Buf);
@@ -267,14 +267,14 @@ begin
     SourceFile.ReadBuffer(Buf, BufSize);
     SourceFile.ReadBuffer(Buf, BufSize);
     Inc64(FChunkBytesRead, BufSize);
     Inc64(FChunkBytesRead, BufSize);
     Dec64(Bytes, BufSize);
     Dec64(Bytes, BufSize);
-    SHA1Update(Context, Buf, BufSize);
+    SHA256Update(Context, Buf, BufSize);
     if CallOptimize then begin
     if CallOptimize then begin
       TransformCallInstructions(Buf, BufSize, True, AddrOffset);
       TransformCallInstructions(Buf, BufSize, True, AddrOffset);
       Inc(AddrOffset, BufSize);  { may wrap, but OK }
       Inc(AddrOffset, BufSize);  { may wrap, but OK }
     end;
     end;
     FCompressor.Compress(Buf, BufSize);
     FCompressor.Compress(Buf, BufSize);
   end;
   end;
-  SHA1Sum := SHA1Final(Context);
+  SHA256Sum := SHA256Final(Context);
 end;
 end;
 
 
 procedure TCompressionHandler.WriteProc(const Buf; BufSize: Longint);
 procedure TCompressionHandler.WriteProc(const Buf; BufSize: Longint);

+ 5 - 5
Projects/Src/Compiler.SetupCompiler.pas

@@ -291,7 +291,7 @@ implementation
 uses
 uses
   Commctrl, TypInfo, AnsiStrings, Math, WideStrUtils,
   Commctrl, TypInfo, AnsiStrings, Math, WideStrUtils,
   PathFunc, Shared.CommonFunc, Compiler.Messages, Shared.SetupEntFunc,
   PathFunc, Shared.CommonFunc, Compiler.Messages, Shared.SetupEntFunc,
-  Shared.FileClass, Compression.Base, Compression.Zlib, Compression.bzlib, SHA1,
+  Shared.FileClass, Compression.Base, Compression.Zlib, Compression.bzlib,
   Shared.LangOptionsSectionDirectives, Shared.ResUpdateFunc, Compiler.ExeUpdateFunc,
   Shared.LangOptionsSectionDirectives, Shared.ResUpdateFunc, Compiler.ExeUpdateFunc,
 {$IFDEF STATICPREPROC}
 {$IFDEF STATICPREPROC}
   ISPP.Preprocess,
   ISPP.Preprocess,
@@ -6999,7 +6999,7 @@ var
             Include(FL.Flags, foCallInstructionOptimized);
             Include(FL.Flags, foCallInstructionOptimized);
 
 
           CH.CompressFile(SourceFile, FL.OriginalSize,
           CH.CompressFile(SourceFile, FL.OriginalSize,
-            foCallInstructionOptimized in FL.Flags, FL.SHA1Sum);
+            foCallInstructionOptimized in FL.Flags, FL.SHA256Sum);
         finally
         finally
           SourceFile.Free;
           SourceFile.Free;
         end;
         end;
@@ -7125,7 +7125,7 @@ var
       end;
       end;
     end else begin
     end else begin
       Filename := SignedUninstallerDir + Format('uninst-%s-%s.e32', [SetupVersion,
       Filename := SignedUninstallerDir + Format('uninst-%s-%s.e32', [SetupVersion,
-        Copy(SHA1DigestToString(SHA1Buf(UnsignedFile.Memory^, UnsignedFileSize)), 1, 10)]);
+        Copy(SHA256DigestToString(SHA256Buf(UnsignedFile.Memory^, UnsignedFileSize)), 1, 10)]);
 
 
       if not NewFileExists(Filename) then begin
       if not NewFileExists(Filename) then begin
         { Create new signed uninstaller file }
         { Create new signed uninstaller file }
@@ -7272,7 +7272,7 @@ var
       fdCreateAlways, faWrite, fsRead);
       fdCreateAlways, faWrite, fsRead);
     try
     try
       S := 'Index' + #9 + 'SourceFilename' + #9 + 'TimeStamp' + #9 +
       S := 'Index' + #9 + 'SourceFilename' + #9 + 'TimeStamp' + #9 +
-        'Version' + #9 + 'SHA1Sum' + #9 + 'OriginalSize' + #9 +
+        'Version' + #9 + 'SHA256Sum' + #9 + 'OriginalSize' + #9 +
         'FirstSlice' + #9 + 'LastSlice' + #9 + 'StartOffset' + #9 +
         'FirstSlice' + #9 + 'LastSlice' + #9 + 'StartOffset' + #9 +
         'ChunkSuboffset' + #9 + 'ChunkCompressedSize' + #9 + 'Encrypted';
         'ChunkSuboffset' + #9 + 'ChunkCompressedSize' + #9 + 'Encrypted';
       F.WriteLine(S);
       F.WriteLine(S);
@@ -7285,7 +7285,7 @@ var
           S := S + Format('%u.%u.%u.%u', [FL.FileVersionMS shr 16,
           S := S + Format('%u.%u.%u.%u', [FL.FileVersionMS shr 16,
             FL.FileVersionMS and $FFFF, FL.FileVersionLS shr 16,
             FL.FileVersionMS and $FFFF, FL.FileVersionLS shr 16,
             FL.FileVersionLS and $FFFF]);
             FL.FileVersionLS and $FFFF]);
-        S := S + #9 + SHA1DigestToString(FL.SHA1Sum) + #9 +
+        S := S + #9 + SHA256DigestToString(FL.SHA256Sum) + #9 +
           Integer64ToStr(FL.OriginalSize) + #9 +
           Integer64ToStr(FL.OriginalSize) + #9 +
           SliceToString(FL.FirstSlice) + #9 +
           SliceToString(FL.FirstSlice) + #9 +
           SliceToString(FL.LastSlice) + #9 +
           SliceToString(FL.LastSlice) + #9 +

+ 5 - 5
Projects/Src/IDE.IDEScintEdit.pas

@@ -171,7 +171,7 @@ type
 implementation
 implementation
 
 
 uses
 uses
-  SysUtils, MD5, ScintInt.InnoSetup;
+  SysUtils, SHA256, ScintInt.InnoSetup;
   
   
 { TIDEScintEdit }
 { TIDEScintEdit }
 
 
@@ -401,11 +401,11 @@ procedure TIDEScintEdit.UpdateIndicators(const Ranges: TScintRangeList;
   function HashRanges(const Ranges: TScintRangeList): String;
   function HashRanges(const Ranges: TScintRangeList): String;
   begin
   begin
     if Ranges.Count > 0 then begin
     if Ranges.Count > 0 then begin
-      var Context: TMD5Context;
-      MD5Init(Context);
+      var Context: TSHA256Context;
+      SHA256Init(Context);
       for var Range in Ranges do
       for var Range in Ranges do
-        MD5Update(Context, Range, SizeOf(Range));
-      Result := MD5DigestToString(MD5Final(Context));
+        SHA256Update(Context, Range, SizeOf(Range));
+      Result := SHA256DigestToString(SHA256Final(Context));
     end else
     end else
       Result := '';
       Result := '';
   end;
   end;

+ 20 - 19
Projects/Src/ISPP.Funcs.pas

@@ -21,8 +21,8 @@ implementation
 
 
 uses
 uses
   SysUtils, IniFiles, Registry, Math, ISPP.Consts, ISPP.Base, ISPP.IdentMan,
   SysUtils, IniFiles, Registry, Math, ISPP.Consts, ISPP.Base, ISPP.IdentMan,
-  ISPP.Sessions, DateUtils, Shared.FileClass, MD5, SHA1, PathFunc, Shared.CommonFunc,
-  Shared.Int64Em, Hash;
+  ISPP.Sessions, DateUtils, Shared.FileClass, MD5, SHA1, SHA256, PathFunc, Shared.CommonFunc,
+  Shared.Int64Em;
   
   
 var
 var
   IsWin64: Boolean;
   IsWin64: Boolean;
@@ -1802,12 +1802,27 @@ end;
 
 
 function GetSHA256OfFile(Ext: Longint; const Params: IIsppFuncParams;
 function GetSHA256OfFile(Ext: Longint; const Params: IIsppFuncParams;
   const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
   const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
+var
+  Buf: array[0..65535] of Byte;
 begin
 begin
   if CheckParams(Params, [evStr], 1, Result) then
   if CheckParams(Params, [evStr], 1, Result) then
   try
   try
     with IInternalFuncParams(Params) do
     with IInternalFuncParams(Params) do
     begin
     begin
-      MakeStr(ResPtr^, THashSHA2.GetHashStringFromFile(Get(0).AsStr, SHA256));
+      var Context: TSHA256Context;
+      SHA256Init(Context);
+      var F := TFile.Create(PrependPath(Ext, Get(0).AsStr), fdOpenExisting, faRead, fsReadWrite);
+      try
+        while True do begin
+          var NumRead := F.Read(Buf, SizeOf(Buf));
+          if NumRead = 0 then
+            Break;
+          SHA256Update(Context, Buf, NumRead);
+        end;
+      finally
+        F.Free;
+      end;
+      MakeStr(ResPtr^, SHA256DigestToString(SHA256Final(Context)));
     end;
     end;
   except
   except
     on E: Exception do
     on E: Exception do
@@ -1826,14 +1841,7 @@ begin
     with IInternalFuncParams(Params) do
     with IInternalFuncParams(Params) do
     begin
     begin
       var S := AnsiString(Get(0).AsStr);
       var S := AnsiString(Get(0).AsStr);
-      var M := TMemoryStream.Create;
-      try
-        M.Write(Pointer(S)^, Length(S)*SizeOf(S[1]));
-        M.Seek(0, soFromBeginning);
-        MakeStr(ResPtr^, THashSHA2.GetHashString(M, SHA256));
-      finally
-        M.Free;
-      end;
+      MakeStr(ResPtr^, SHA256DigestToString(SHA256Buf(Pointer(S)^, Length(S)*SizeOf(S[1]))));
     end;
     end;
   except
   except
     on E: Exception do
     on E: Exception do
@@ -1852,14 +1860,7 @@ begin
     with IInternalFuncParams(Params) do
     with IInternalFuncParams(Params) do
     begin
     begin
       var S := Get(0).AsStr;
       var S := Get(0).AsStr;
-      var M := TMemoryStream.Create;
-      try
-        M.Write(Pointer(S)^, Length(S)*SizeOf(S[1]));
-        M.Seek(0, soFromBeginning);
-        MakeStr(ResPtr^, THashSHA2.GetHashString(M, SHA256));
-      finally
-        M.Free;
-      end;
+      MakeStr(ResPtr^, SHA256DigestToString(SHA256Buf(Pointer(S)^, Length(S)*SizeOf(S[1]))));
     end;
     end;
   except
   except
     on E: Exception do
     on E: Exception do

+ 8 - 8
Projects/Src/Setup.FileExtractor.pas

@@ -50,9 +50,9 @@ procedure FreeFileExtractor;
 implementation
 implementation
 
 
 uses
 uses
-  Hash, PathFunc, Shared.CommonFunc, Setup.MainFunc, SetupLdrAndSetup.Messages,
+  PathFunc, Shared.CommonFunc, Setup.MainFunc, SetupLdrAndSetup.Messages,
   Shared.SetupMessageIDs, Setup.InstFunc, Compression.Zlib, Compression.bzlib,
   Shared.SetupMessageIDs, Setup.InstFunc, Compression.Zlib, Compression.bzlib,
-  Compression.LZMADecompressor, SHA1, Setup.LoggingFunc, Setup.NewDiskForm;
+  Compression.LZMADecompressor, SHA256, Setup.LoggingFunc, Setup.NewDiskForm;
 
 
 var
 var
   FFileExtractor: TFileExtractor;
   FFileExtractor: TFileExtractor;
@@ -191,7 +191,7 @@ procedure TFileExtractor.SeekTo(const FL: TSetupFileLocationEntry;
   procedure InitDecryption;
   procedure InitDecryption;
   begin
   begin
     { Initialize the key, which is the SHA-256 hash of FCryptKey }
     { Initialize the key, which is the SHA-256 hash of FCryptKey }
-    var Key := THashSHA2.GetHashBytes(FCryptKey, SHA256);
+    var Key := SHA256Buf(Pointer(FCryptKey)^, Length(FCryptKey)*SizeOf(FCryptKey[1]));
 
 
     { Recreate the unique nonce from the base nonce }
     { Recreate the unique nonce from the base nonce }
     var Nonce := SetupHeader.EncryptionBaseNonce;
     var Nonce := SetupHeader.EncryptionBaseNonce;
@@ -315,7 +315,7 @@ procedure TFileExtractor.DecompressFile(const FL: TSetupFileLocationEntry;
   const VerifyChecksum: Boolean);
   const VerifyChecksum: Boolean);
 var
 var
   BytesLeft: Integer64;
   BytesLeft: Integer64;
-  Context: TSHA1Context;
+  Context: TSHA256Context;
   AddrOffset: LongWord;
   AddrOffset: LongWord;
   BufSize: Cardinal;
   BufSize: Cardinal;
   Buf: array[0..65535] of Byte;
   Buf: array[0..65535] of Byte;
@@ -334,7 +334,7 @@ begin
     DestF.Truncate;
     DestF.Truncate;
     DestF.Seek(0);
     DestF.Seek(0);
 
 
-    SHA1Init(Context);
+    SHA256Init(Context);
 
 
     try
     try
       AddrOffset := 0;
       AddrOffset := 0;
@@ -351,7 +351,7 @@ begin
           Inc(AddrOffset, BufSize);  { may wrap, but OK }
           Inc(AddrOffset, BufSize);  { may wrap, but OK }
         end;
         end;
         Dec64(BytesLeft, BufSize);
         Dec64(BytesLeft, BufSize);
-        SHA1Update(Context, Buf, BufSize);
+        SHA256Update(Context, Buf, BufSize);
         DestF.WriteBuffer(Buf, BufSize);
         DestF.WriteBuffer(Buf, BufSize);
 
 
         if Assigned(ProgressProc) then
         if Assigned(ProgressProc) then
@@ -362,8 +362,8 @@ begin
         SourceIsCorrupted(E.Message);
         SourceIsCorrupted(E.Message);
     end;
     end;
 
 
-    if VerifyChecksum and not SHA1DigestsEqual(SHA1Final(Context), FL.SHA1Sum) then
-      SourceIsCorrupted('SHA-1 hash mismatch');
+    if VerifyChecksum and not SHA256DigestsEqual(SHA256Final(Context), FL.SHA256Sum) then
+      SourceIsCorrupted('SHA-256 hash mismatch');
   finally
   finally
     Dec(FEntered);
     Dec(FEntered);
   end;
   end;

+ 22 - 102
Projects/Src/Setup.InstFunc.pas

@@ -12,7 +12,7 @@ unit Setup.InstFunc;
 interface
 interface
 
 
 uses
 uses
-  Windows, SysUtils, Shared.Int64Em, MD5, SHA1, Shared.CommonFunc;
+  Windows, SysUtils, Shared.Int64Em, SHA256, Shared.CommonFunc;
 
 
 type
 type
   PSimpleStringListArray = ^TSimpleStringListArray;
   PSimpleStringListArray = ^TSimpleStringListArray;
@@ -58,15 +58,9 @@ function GenerateNonRandomUniqueTempDir(const LimitCurrentUserSidAccess: Boolean
 function GetComputerNameString: String;
 function GetComputerNameString: String;
 function GetFileDateTime(const DisableFsRedir: Boolean; const Filename: String;
 function GetFileDateTime(const DisableFsRedir: Boolean; const Filename: String;
   var DateTime: TFileTime): Boolean;
   var DateTime: TFileTime): Boolean;
-function GetMD5OfFile(const DisableFsRedir: Boolean; const Filename: String): TMD5Digest;
-function GetMD5OfAnsiString(const S: AnsiString): TMD5Digest;
-function GetMD5OfUnicodeString(const S: UnicodeString): TMD5Digest;
-function GetSHA1OfFile(const DisableFsRedir: Boolean; const Filename: String): TSHA1Digest;
-function GetSHA1OfAnsiString(const S: AnsiString): TSHA1Digest;
-function GetSHA1OfUnicodeString(const S: UnicodeString): TSHA1Digest;
-function GetSHA256OfFile(const DisableFsRedir: Boolean; const Filename: String): String;
-function GetSHA256OfAnsiString(const S: AnsiString): String;
-function GetSHA256OfUnicodeString(const S: UnicodeString): String;
+function GetSHA256OfFile(const DisableFsRedir: Boolean; const Filename: String): TSHA256Digest;
+function GetSHA256OfAnsiString(const S: AnsiString): TSHA256Digest;
+function GetSHA256OfUnicodeString(const S: UnicodeString): TSHA256Digest;
 function GetRegRootKeyName(const RootKey: HKEY): String;
 function GetRegRootKeyName(const RootKey: HKEY): String;
 function GetSpaceOnDisk(const DisableFsRedir: Boolean; const DriveRoot: String;
 function GetSpaceOnDisk(const DisableFsRedir: Boolean; const DriveRoot: String;
   var FreeBytes, TotalBytes: Integer64): Boolean;
   var FreeBytes, TotalBytes: Integer64): Boolean;
@@ -87,7 +81,7 @@ procedure InternalErrorFmt(const S: String; const Args: array of const);
 function IsDirEmpty(const DisableFsRedir: Boolean; const Dir: String): Boolean;
 function IsDirEmpty(const DisableFsRedir: Boolean; const Dir: String): Boolean;
 function IsProtectedSystemFile(const DisableFsRedir: Boolean;
 function IsProtectedSystemFile(const DisableFsRedir: Boolean;
   const Filename: String): Boolean;
   const Filename: String): Boolean;
-function MakePendingFileRenameOperationsChecksum: TMD5Digest;
+function MakePendingFileRenameOperationsChecksum: TSHA256Digest;
 function ModifyPifFile(const Filename: String; const CloseOnExit: Boolean): Boolean;
 function ModifyPifFile(const Filename: String; const CloseOnExit: Boolean): Boolean;
 procedure RaiseFunctionFailedError(const FunctionName: String);
 procedure RaiseFunctionFailedError(const FunctionName: String);
 procedure RaiseOleError(const FunctionName: String; const ResultCode: HRESULT);
 procedure RaiseOleError(const FunctionName: String; const ResultCode: HRESULT);
@@ -106,7 +100,7 @@ implementation
 uses
 uses
   Messages, ShellApi, PathFunc, SetupLdrAndSetup.InstFunc, SetupLdrAndSetup.Messages,
   Messages, ShellApi, PathFunc, SetupLdrAndSetup.InstFunc, SetupLdrAndSetup.Messages,
   Shared.SetupMessageIDs, Shared.FileClass, SetupLdrAndSetup.RedirFunc, Shared.SetupTypes,
   Shared.SetupMessageIDs, Shared.FileClass, SetupLdrAndSetup.RedirFunc, Shared.SetupTypes,
-  Hash, Classes, RegStr, Math;
+  Classes, RegStr, Math;
 
 
 procedure InternalError(const Id: String);
 procedure InternalError(const Id: String);
 begin
 begin
@@ -556,110 +550,36 @@ begin
   DateTime.dwHighDateTime := 0;
   DateTime.dwHighDateTime := 0;
 end;
 end;
 
 
-function GetMD5OfFile(const DisableFsRedir: Boolean; const Filename: String): TMD5Digest;
-{ Gets MD5 sum of the file Filename. An exception will be raised upon
-  failure. }
-var
-  Buf: array[0..65535] of Byte;
-begin
-  var Context: TMD5Context;
-  MD5Init(Context);
-  var F := TFileRedir.Create(DisableFsRedir, Filename, fdOpenExisting, faRead, fsReadWrite);
-  try
-    while True do begin
-      var NumRead := F.Read(Buf, SizeOf(Buf));
-      if NumRead = 0 then
-        Break;
-      MD5Update(Context, Buf, NumRead);
-    end;
-  finally
-    F.Free;
-  end;
-  Result := MD5Final(Context);
-end;
-
-function GetSHA1OfFile(const DisableFsRedir: Boolean; const Filename: String): TSHA1Digest;
-{ Gets SHA-1 sum of the file Filename. An exception will be raised upon
+function GetSHA256OfFile(const DisableFsRedir: Boolean; const Filename: String): TSHA256Digest;
+{ Gets SHA-256 sum as a string of the file Filename. An exception will be raised upon
   failure. }
   failure. }
 var
 var
   Buf: array[0..65535] of Byte;
   Buf: array[0..65535] of Byte;
 begin
 begin
-  var Context: TSHA1Context;
-  SHA1Init(Context);
+  var Context: TSHA256Context;
+  SHA256Init(Context);
   var F := TFileRedir.Create(DisableFsRedir, Filename, fdOpenExisting, faRead, fsReadWrite);
   var F := TFileRedir.Create(DisableFsRedir, Filename, fdOpenExisting, faRead, fsReadWrite);
   try
   try
     while True do begin
     while True do begin
       var NumRead := F.Read(Buf, SizeOf(Buf));
       var NumRead := F.Read(Buf, SizeOf(Buf));
       if NumRead = 0 then
       if NumRead = 0 then
         Break;
         Break;
-      SHA1Update(Context, Buf, NumRead);
+      SHA256Update(Context, Buf, NumRead);
     end;
     end;
   finally
   finally
     F.Free;
     F.Free;
   end;
   end;
-  Result := SHA1Final(Context);
-end;
-
-function GetSHA256OfFile(const DisableFsRedir: Boolean; const Filename: String): String;
-{ Gets SHA-256 sum as a string of the file Filename. An exception will be raised upon
-  failure. }
-begin
-  var PrevState: TPreviousFsRedirectionState;
-  if not DisableFsRedirectionIf(DisableFsRedir, PrevState) then
-    InternalError('GetSHA256OfFile: DisableFsRedirectionIf failed.');
-  try
-    Result := THashSHA2.GetHashStringFromFile(Filename, SHA256);
-  finally
-    RestoreFsRedirection(PrevState);
-  end;
-end;
-
-function GetMD5OfAnsiString(const S: AnsiString): TMD5Digest;
-begin
-  Result := MD5Buf(Pointer(S)^, Length(S)*SizeOf(S[1]));
+  Result := SHA256Final(Context);
 end;
 end;
 
 
-function GetMD5OfUnicodeString(const S: UnicodeString): TMD5Digest;
+function GetSHA256OfAnsiString(const S: AnsiString): TSHA256Digest;
 begin
 begin
-  Result := MD5Buf(Pointer(S)^, Length(S)*SizeOf(S[1]));
+  Result := SHA256Buf(Pointer(S)^, Length(S)*SizeOf(S[1]));
 end;
 end;
 
 
-function GetSHA1OfAnsiString(const S: AnsiString): TSHA1Digest;
+function GetSHA256OfUnicodeString(const S: UnicodeString): TSHA256Digest;
 begin
 begin
-  Result := SHA1Buf(Pointer(S)^, Length(S)*SizeOf(S[1]));
-end;
-
-function GetSHA1OfUnicodeString(const S: UnicodeString): TSHA1Digest;
-begin
-  Result := SHA1Buf(Pointer(S)^, Length(S)*SizeOf(S[1]));
-end;
-
-function GetSHA256OfAnsiString(const S: AnsiString): String;
-var
-  M: TMemoryStream;
-begin
-  M := TMemoryStream.Create;
-  try
-    M.Write(Pointer(S)^, Length(S)*SizeOf(S[1]));
-    M.Seek(0, soFromBeginning);
-    Result := THashSHA2.GetHashString(M, SHA256);
-  finally
-    M.Free;
-  end;
-end;
-
-function GetSHA256OfUnicodeString(const S: UnicodeString): String;
-var
-  M: TMemoryStream;
-begin
-  M := TMemoryStream.Create;
-  try
-    M.Write(Pointer(S)^, Length(S)*SizeOf(S[1]));
-    M.Seek(0, soFromBeginning);
-    Result := THashSHA2.GetHashString(M, SHA256);
-  finally
-    M.Free;
-  end;
+  Result := SHA256Buf(Pointer(S)^, Length(S)*SizeOf(S[1]));
 end;
 end;
 
 
 var
 var
@@ -940,31 +860,31 @@ begin
     Result := '';
     Result := '';
 end;
 end;
 
 
-function MakePendingFileRenameOperationsChecksum: TMD5Digest;
+function MakePendingFileRenameOperationsChecksum: TSHA256Digest;
 { Calculates a checksum of the current PendingFileRenameOperations registry
 { Calculates a checksum of the current PendingFileRenameOperations registry
   value The caller can use this checksum to determine if
   value The caller can use this checksum to determine if
   PendingFileRenameOperations was changed (perhaps by another program). }
   PendingFileRenameOperations was changed (perhaps by another program). }
 var
 var
-  Context: TMD5Context;
+  Context: TSHA256Context;
   K: HKEY;
   K: HKEY;
   S: String;
   S: String;
 begin
 begin
-  MD5Init(Context);
+  SHA256Init(Context);
   try
   try
     if RegOpenKeyExView(rvDefault, HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager',
     if RegOpenKeyExView(rvDefault, HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager',
        0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
        0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
       if RegQueryMultiStringValue(K, 'PendingFileRenameOperations', S) then
       if RegQueryMultiStringValue(K, 'PendingFileRenameOperations', S) then
-        MD5Update(Context, S[1], Length(S)*SizeOf(S[1]));
+        SHA256Update(Context, S[1], Length(S)*SizeOf(S[1]));
       { When "PendingFileRenameOperations" is full, it spills over into
       { When "PendingFileRenameOperations" is full, it spills over into
         "PendingFileRenameOperations2" }
         "PendingFileRenameOperations2" }
       if RegQueryMultiStringValue(K, 'PendingFileRenameOperations2', S) then
       if RegQueryMultiStringValue(K, 'PendingFileRenameOperations2', S) then
-        MD5Update(Context, S[1], Length(S)*SizeOf(S[1]));
+        SHA256Update(Context, S[1], Length(S)*SizeOf(S[1]));
       RegCloseKey(K);
       RegCloseKey(K);
     end;
     end;
   except
   except
     { don't propagate exceptions }
     { don't propagate exceptions }
   end;
   end;
-  Result := MD5Final(Context);
+  Result := SHA256Final(Context);
 end;
 end;
 
 
 procedure EnumFileReplaceOperationsFilenames(const EnumFunc: TEnumFROFilenamesProc;
 procedure EnumFileReplaceOperationsFilenames(const EnumFunc: TEnumFROFilenamesProc;

+ 23 - 22
Projects/Src/Setup.Install.pas

@@ -31,7 +31,7 @@ uses
   Windows, SysUtils, Messages, Classes, Forms, ShlObj, Shared.Struct, Setup.UninstallLog, Shared.SetupTypes,
   Windows, SysUtils, Messages, Classes, Forms, ShlObj, Shared.Struct, Setup.UninstallLog, Shared.SetupTypes,
   SetupLdrAndSetup.InstFunc, Setup.InstFunc, Setup.InstFunc.Ole, Setup.SecurityFunc, SetupLdrAndSetup.Messages,
   SetupLdrAndSetup.InstFunc, Setup.InstFunc, Setup.InstFunc.Ole, Setup.SecurityFunc, SetupLdrAndSetup.Messages,
   Setup.MainFunc, Setup.LoggingFunc, Setup.FileExtractor, Shared.FileClass,
   Setup.MainFunc, Setup.LoggingFunc, Setup.FileExtractor, Shared.FileClass,
-  Compression.Base, SHA1, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc, SetupLdrAndSetup.RedirFunc, Shared.Int64Em, Shared.SetupMessageIDs,
+  Compression.Base, SHA256, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc, SetupLdrAndSetup.RedirFunc, Shared.Int64Em, Shared.SetupMessageIDs,
   Setup.WizardForm, Shared.DebugStruct, Setup.DebugClient, Shared.VerInfoFunc, Setup.ScriptRunner, Setup.RegDLL, Setup.Helper,
   Setup.WizardForm, Shared.DebugStruct, Setup.DebugClient, Shared.VerInfoFunc, Setup.ScriptRunner, Setup.RegDLL, Setup.Helper,
   Shared.ResUpdateFunc, Setup.DotNetFunc, TaskbarProgressFunc, NewProgressBar, RestartManager,
   Shared.ResUpdateFunc, Setup.DotNetFunc, TaskbarProgressFunc, NewProgressBar, RestartManager,
   Net.HTTPClient, Net.URLClient, NetEncoding, RegStr;
   Net.HTTPClient, Net.URLClient, NetEncoding, RegStr;
@@ -237,12 +237,12 @@ begin
     Result := '(invalid)';
     Result := '(invalid)';
 end;
 end;
 
 
-function TryToGetSHA1OfFile(const DisableFsRedir: Boolean; const Filename: String;
-  var Sum: TSHA1Digest): Boolean;
-{ Like GetSHA1OfFile but traps exceptions locally. Returns True if successful. }
+function TryToGetSHA256OfFile(const DisableFsRedir: Boolean; const Filename: String;
+  var Sum: TSHA256Digest): Boolean;
+{ Like GetSHA256OfFile but traps exceptions locally. Returns True if successful. }
 begin
 begin
   try
   try
-    Sum := GetSHA1OfFile(DisableFsRedir, Filename);
+    Sum := GetSHA256OfFile(DisableFsRedir, Filename);
     Result := True;
     Result := True;
   except
   except
     Result := False;
     Result := False;
@@ -877,17 +877,17 @@ var
 
 
   procedure BindUninstallMsgDataToExe(const F: TFile);
   procedure BindUninstallMsgDataToExe(const F: TFile);
   var
   var
-    UniqueValue: TSHA1Digest;
+    UniqueValue: TSHA256Digest;
     UninstallerMsgTail: TUninstallerMsgTail;
     UninstallerMsgTail: TUninstallerMsgTail;
   begin
   begin
     F.SeekToEnd;
     F.SeekToEnd;
 
 
     { First append the hash of AppId so that unins*.exe files from different
     { First append the hash of AppId so that unins*.exe files from different
-      applications won't have the same MD5 sum. This is done to combat broken
-      anti-spyware programs that catch all unins*.exe files with certain MD5
+      applications won't have the same file hash. This is done to combat broken
+      anti-spyware programs that catch all unins*.exe files with certain hash
       sums just because some piece of spyware was deployed with Inno Setup and
       sums just because some piece of spyware was deployed with Inno Setup and
       had the unins*.exe file in its directory. }
       had the unins*.exe file in its directory. }
-    UniqueValue := GetSHA1OfUnicodeString(ExpandedAppId);
+    UniqueValue := GetSHA256OfUnicodeString(ExpandedAppId);
     F.WriteBuffer(UniqueValue, SizeOf(UniqueValue));
     F.WriteBuffer(UniqueValue, SizeOf(UniqueValue));
 
 
     UninstallerMsgTail.ID := UninstallerMsgTailID;
     UninstallerMsgTail.ID := UninstallerMsgTailID;
@@ -1080,7 +1080,7 @@ var
     CurFileVersionInfoValid: Boolean;
     CurFileVersionInfoValid: Boolean;
     CurFileVersionInfo, ExistingVersionInfo: TFileVersionNumbers;
     CurFileVersionInfo, ExistingVersionInfo: TFileVersionNumbers;
     CurFileDateValid, ExistingFileDateValid: Boolean;
     CurFileDateValid, ExistingFileDateValid: Boolean;
-    CurFileHash, ExistingFileHash: TSHA1Digest;
+    CurFileHash, ExistingFileHash: TSHA256Digest;
     IsProtectedFile, AllowTimeStampComparison: Boolean;
     IsProtectedFile, AllowTimeStampComparison: Boolean;
     DeleteFlags: Longint;
     DeleteFlags: Longint;
     CurFileDate, ExistingFileDate: TFileTime;
     CurFileDate, ExistingFileDate: TFileTime;
@@ -1254,27 +1254,27 @@ var
                    (ExistingVersionInfo.LS = CurFileVersionInfo.LS) and
                    (ExistingVersionInfo.LS = CurFileVersionInfo.LS) and
                    not(foOverwriteSameVersion in CurFile^.Options) then begin
                    not(foOverwriteSameVersion in CurFile^.Options) then begin
                   if foReplaceSameVersionIfContentsDiffer in CurFile^.Options then begin
                   if foReplaceSameVersionIfContentsDiffer in CurFile^.Options then begin
-                    { Get the two files' SHA-1 hashes and compare them }
-                    if TryToGetSHA1OfFile(DisableFsRedir, DestFile, ExistingFileHash) then begin
+                    { Get the two files' SHA-256 hashes and compare them }
+                    if TryToGetSHA256OfFile(DisableFsRedir, DestFile, ExistingFileHash) then begin
                       if Assigned(CurFileLocation) then
                       if Assigned(CurFileLocation) then
-                        CurFileHash := CurFileLocation^.SHA1Sum
+                        CurFileHash := CurFileLocation^.SHA256Sum
                       else begin
                       else begin
                         LastOperation := SetupMessages[msgErrorReadingSource];
                         LastOperation := SetupMessages[msgErrorReadingSource];
-                        { This GetSHA1OfFile call could raise an exception, but
+                        { This GetSHA256OfFile call could raise an exception, but
                           it's very unlikely since we were already able to
                           it's very unlikely since we were already able to
                           successfully read the file's version info. }
                           successfully read the file's version info. }
-                        CurFileHash := GetSHA1OfFile(DisableFsRedir, ASourceFile);
+                        CurFileHash := GetSHA256OfFile(DisableFsRedir, ASourceFile);
                         LastOperation := SetupMessages[msgErrorReadingExistingDest];
                         LastOperation := SetupMessages[msgErrorReadingExistingDest];
                       end;
                       end;
-                      { If the two files' SHA-1 hashes are equal, skip the file }
-                      if SHA1DigestsEqual(ExistingFileHash, CurFileHash) then begin
-                        Log('Existing file''s SHA-1 hash matches our file. Skipping.');
+                      { If the two files' SHA-256 hashes are equal, skip the file }
+                      if SHA256DigestsEqual(ExistingFileHash, CurFileHash) then begin
+                        Log('Existing file''s SHA-256 hash matches our file. Skipping.');
                         goto Skip;
                         goto Skip;
                       end;
                       end;
-                      Log('Existing file''s SHA-1 hash is different from our file. Proceeding.');
+                      Log('Existing file''s SHA-256 hash is different from our file. Proceeding.');
                     end
                     end
                     else
                     else
-                      Log('Failed to read existing file''s SHA-1 hash. Proceeding.');
+                      Log('Failed to read existing file''s SHA-256 hash. Proceeding.');
                   end
                   end
                   else begin
                   else begin
                     { Skip the file or fall back to time stamp comparison }
                     { Skip the file or fall back to time stamp comparison }
@@ -3511,7 +3511,8 @@ begin
 
 
   { Prepare directory }
   { Prepare directory }
   if FileExists(DestFile) then begin
   if FileExists(DestFile) then begin
-    if (RequiredSHA256OfFile <> '') and (RequiredSHA256OfFile = GetSHA256OfFile(DisableFsRedir, DestFile)) then begin
+    if (RequiredSHA256OfFile <> '') and
+       (RequiredSHA256OfFile = SHA256DigestToString(GetSHA256OfFile(DisableFsRedir, DestFile))) then begin
       Log('  File already downloaded.');
       Log('  File already downloaded.');
       Result := 0;
       Result := 0;
       Exit;
       Exit;
@@ -3574,7 +3575,7 @@ begin
       { Check hash if specified, otherwise check everything else we can check }
       { Check hash if specified, otherwise check everything else we can check }
       if RequiredSHA256OfFile <> '' then begin
       if RequiredSHA256OfFile <> '' then begin
         try
         try
-          SHA256OfFile := GetSHA256OfFile(DisableFsRedir, TempFile);
+          SHA256OfFile := SHA256DigestToString(GetSHA256OfFile(DisableFsRedir, TempFile));
         except on E: Exception do
         except on E: Exception do
           raise Exception.Create(FmtSetupMessage(msgErrorFileHash1, [E.Message]));
           raise Exception.Create(FmtSetupMessage(msgErrorFileHash1, [E.Message]));
         end;
         end;

+ 3 - 3
Projects/Src/Setup.MainForm.pas

@@ -49,7 +49,7 @@ var
 implementation
 implementation
 
 
 uses
 uses
-  Forms, Graphics, ShlObj, MD5, RestartManager,
+  Forms, Graphics, ShlObj, SHA256, RestartManager,
   Shared.CommonFunc, Shared.CommonFunc.Vcl, Shared.SetupMessageIDs,
   Shared.CommonFunc, Shared.CommonFunc.Vcl, Shared.SetupMessageIDs,
   SetupLdrAndSetup.Messages, SetupLdrAndSetup.RedirFunc, Setup.Install,
   SetupLdrAndSetup.Messages, SetupLdrAndSetup.RedirFunc, Setup.Install,
   Setup.InstFunc, Setup.WizardForm, Setup.LoggingFunc;
   Setup.InstFunc, Setup.WizardForm, Setup.LoggingFunc;
@@ -328,7 +328,7 @@ function TMainForm.Install: Boolean;
   procedure ProcessRunEntries;
   procedure ProcessRunEntries;
   var
   var
     CheckIfRestartNeeded: Boolean;
     CheckIfRestartNeeded: Boolean;
-    ChecksumBefore, ChecksumAfter: TMD5Digest;
+    ChecksumBefore, ChecksumAfter: TSHA256Digest;
     WindowDisabler: TWindowDisabler;
     WindowDisabler: TWindowDisabler;
     I: Integer;
     I: Integer;
     RunEntry: PSetupRunEntry;
     RunEntry: PSetupRunEntry;
@@ -388,7 +388,7 @@ function TMainForm.Install: Boolean;
         WindowDisabler.Free;
         WindowDisabler.Free;
         if CheckIfRestartNeeded then begin
         if CheckIfRestartNeeded then begin
           ChecksumAfter := MakePendingFileRenameOperationsChecksum;
           ChecksumAfter := MakePendingFileRenameOperationsChecksum;
-          if not MD5DigestsEqual(ChecksumBefore, ChecksumAfter) then
+          if not SHA256DigestsEqual(ChecksumBefore, ChecksumAfter) then
             NeedsRestart := True;
             NeedsRestart := True;
         end;
         end;
       end;
       end;

+ 70 - 5
Projects/Src/Setup.ScriptFunc.pas

@@ -25,7 +25,7 @@ uses
   Shared.CommonFunc, Shared.FileClass, SetupLdrAndSetup.RedirFunc,
   Shared.CommonFunc, Shared.FileClass, SetupLdrAndSetup.RedirFunc,
   Setup.Install, SetupLdrAndSetup.InstFunc, Setup.InstFunc, Setup.InstFunc.Ole, SetupLdrAndSetup.Messages,
   Setup.Install, SetupLdrAndSetup.InstFunc, Setup.InstFunc, Setup.InstFunc.Ole, SetupLdrAndSetup.Messages,
   Shared.SetupMessageIDs, Setup.NewDiskForm, BrowseFunc, Setup.WizardForm, Shared.VerInfoFunc,
   Shared.SetupMessageIDs, Setup.NewDiskForm, BrowseFunc, Setup.WizardForm, Shared.VerInfoFunc,
-  Shared.SetupTypes, Shared.Int64Em, MD5, SHA1, Setup.LoggingFunc, Setup.SetupForm, Setup.RegDLL, Setup.Helper,
+  Shared.SetupTypes, Shared.Int64Em, MD5, SHA1, SHA256, Setup.LoggingFunc, Setup.SetupForm, Setup.RegDLL, Setup.Helper,
   Setup.SpawnClient, Setup.UninstallProgressForm, ASMInline, Setup.DotNetFunc,
   Setup.SpawnClient, Setup.UninstallProgressForm, ASMInline, Setup.DotNetFunc,
   Shared.DotNetVersion, Setup.MsiFunc, BitmapImage;
   Shared.DotNetVersion, Setup.MsiFunc, BitmapImage;
 
 
@@ -849,6 +849,71 @@ begin
 end;
 end;
 
 
 function InstFuncProc(Caller: TPSExec; Proc: TPSExternalProcRec; Global, Stack: TPSStack): Boolean;
 function InstFuncProc(Caller: TPSExec; Proc: TPSExternalProcRec; Global, Stack: TPSStack): Boolean;
+
+  function GetMD5OfFile(const DisableFsRedir: Boolean; const Filename: String): TMD5Digest;
+  { Gets MD5 sum of the file Filename. An exception will be raised upon
+    failure. }
+  var
+    Buf: array[0..65535] of Byte;
+  begin
+    var Context: TMD5Context;
+    MD5Init(Context);
+    var F := TFileRedir.Create(DisableFsRedir, Filename, fdOpenExisting, faRead, fsReadWrite);
+    try
+      while True do begin
+        var NumRead := F.Read(Buf, SizeOf(Buf));
+        if NumRead = 0 then
+          Break;
+        MD5Update(Context, Buf, NumRead);
+      end;
+    finally
+      F.Free;
+    end;
+    Result := MD5Final(Context);
+  end;
+
+  function GetSHA1OfFile(const DisableFsRedir: Boolean; const Filename: String): TSHA1Digest;
+  { Gets SHA-1 sum of the file Filename. An exception will be raised upon
+    failure. }
+  var
+    Buf: array[0..65535] of Byte;
+  begin
+    var Context: TSHA1Context;
+    SHA1Init(Context);
+    var F := TFileRedir.Create(DisableFsRedir, Filename, fdOpenExisting, faRead, fsReadWrite);
+    try
+      while True do begin
+        var NumRead := F.Read(Buf, SizeOf(Buf));
+        if NumRead = 0 then
+          Break;
+        SHA1Update(Context, Buf, NumRead);
+      end;
+    finally
+      F.Free;
+    end;
+    Result := SHA1Final(Context);
+  end;
+
+  function GetMD5OfAnsiString(const S: AnsiString): TMD5Digest;
+  begin
+    Result := MD5Buf(Pointer(S)^, Length(S)*SizeOf(S[1]));
+  end;
+
+  function GetMD5OfUnicodeString(const S: UnicodeString): TMD5Digest;
+  begin
+    Result := MD5Buf(Pointer(S)^, Length(S)*SizeOf(S[1]));
+  end;
+
+  function GetSHA1OfAnsiString(const S: AnsiString): TSHA1Digest;
+  begin
+    Result := SHA1Buf(Pointer(S)^, Length(S)*SizeOf(S[1]));
+  end;
+
+  function GetSHA1OfUnicodeString(const S: UnicodeString): TSHA1Digest;
+  begin
+    Result := SHA1Buf(Pointer(S)^, Length(S)*SizeOf(S[1]));
+end;
+
 var
 var
   PStart: Cardinal;
   PStart: Cardinal;
   Filename: String;
   Filename: String;
@@ -890,11 +955,11 @@ begin
   end else if Proc.Name = 'GETSHA1OFUNICODESTRING' then begin
   end else if Proc.Name = 'GETSHA1OFUNICODESTRING' then begin
     Stack.SetString(PStart, SHA1DigestToString(GetSHA1OfUnicodeString(Stack.GetString(PStart-1))));
     Stack.SetString(PStart, SHA1DigestToString(GetSHA1OfUnicodeString(Stack.GetString(PStart-1))));
   end else if Proc.Name = 'GETSHA256OFFILE' then begin
   end else if Proc.Name = 'GETSHA256OFFILE' then begin
-    Stack.SetString(PStart, GetSHA256OfFile(ScriptFuncDisableFsRedir, Stack.GetString(PStart-1)));
+    Stack.SetString(PStart, SHA256DigestToString(GetSHA256OfFile(ScriptFuncDisableFsRedir, Stack.GetString(PStart-1))));
   end else if Proc.Name = 'GETSHA256OFSTRING' then begin
   end else if Proc.Name = 'GETSHA256OFSTRING' then begin
-    Stack.SetString(PStart, GetSHA256OfAnsiString(StackGetAnsiString(Stack, PStart-1)));
+    Stack.SetString(PStart, SHA256DigestToString(GetSHA256OfAnsiString(StackGetAnsiString(Stack, PStart-1))));
   end else if Proc.Name = 'GETSHA256OFUNICODESTRING' then begin
   end else if Proc.Name = 'GETSHA256OFUNICODESTRING' then begin
-    Stack.SetString(PStart, GetSHA256OfUnicodeString(Stack.GetString(PStart-1)));
+    Stack.SetString(PStart, SHA256DigestToString(GetSHA256OfUnicodeString(Stack.GetString(PStart-1))));
   end else if Proc.Name = 'GETSPACEONDISK' then begin
   end else if Proc.Name = 'GETSPACEONDISK' then begin
     if GetSpaceOnDisk(ScriptFuncDisableFsRedir, Stack.GetString(PStart-1), FreeBytes, TotalBytes) then begin
     if GetSpaceOnDisk(ScriptFuncDisableFsRedir, Stack.GetString(PStart-1), FreeBytes, TotalBytes) then begin
       if Stack.GetBool(PStart-2) then begin
       if Stack.GetBool(PStart-2) then begin
@@ -999,7 +1064,7 @@ begin
   end else if Proc.Name = 'ISPROTECTEDSYSTEMFILE' then begin
   end else if Proc.Name = 'ISPROTECTEDSYSTEMFILE' then begin
     Stack.SetBool(PStart, IsProtectedSystemFile(ScriptFuncDisableFsRedir, Stack.GetString(PStart-1)));
     Stack.SetBool(PStart, IsProtectedSystemFile(ScriptFuncDisableFsRedir, Stack.GetString(PStart-1)));
   end else if Proc.Name = 'MAKEPENDINGFILERENAMEOPERATIONSCHECKSUM' then begin
   end else if Proc.Name = 'MAKEPENDINGFILERENAMEOPERATIONSCHECKSUM' then begin
-    Stack.SetString(PStart, MD5DigestToString(MakePendingFileRenameOperationsChecksum));
+    Stack.SetString(PStart, SHA256DigestToString(MakePendingFileRenameOperationsChecksum));
   end else if Proc.Name = 'MODIFYPIFFILE' then begin
   end else if Proc.Name = 'MODIFYPIFFILE' then begin
     Stack.SetBool(PStart, ModifyPifFile(Stack.GetString(PStart-1), Stack.GetBool(PStart-2)));
     Stack.SetBool(PStart, ModifyPifFile(Stack.GetString(PStart-1), Stack.GetBool(PStart-2)));
   end else if Proc.Name = 'REGISTERSERVER' then begin
   end else if Proc.Name = 'REGISTERSERVER' then begin

+ 1 - 1
Projects/Src/Setup.WizardForm.pas

@@ -343,7 +343,7 @@ implementation
 
 
 uses
 uses
   ShellApi, ShlObj, Types, SetupLdrAndSetup.Messages, Setup.MainForm, Setup.MainFunc, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc,
   ShellApi, ShlObj, Types, SetupLdrAndSetup.Messages, Setup.MainForm, Setup.MainFunc, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc,
-  MD5, Setup.InstFunc, Setup.SelectFolderForm, Setup.FileExtractor, Setup.LoggingFunc, RestartManager, Setup.ScriptRunner;
+  Setup.InstFunc, Setup.SelectFolderForm, Setup.FileExtractor, Setup.LoggingFunc, RestartManager, Setup.ScriptRunner;
 
 
 {$R *.DFM}
 {$R *.DFM}
 
 

+ 2 - 2
Projects/Src/Shared.Struct.pas

@@ -13,7 +13,7 @@ unit Shared.Struct;
 interface
 interface
 
 
 uses
 uses
-  Windows, Shared.Int64Em, SHA1, SHA256;
+  Windows, Shared.Int64Em, SHA256;
 
 
 const
 const
   SetupTitle = 'Inno Setup';
   SetupTitle = 'Inno Setup';
@@ -255,7 +255,7 @@ type
     ChunkSuboffset: Integer64;
     ChunkSuboffset: Integer64;
     OriginalSize: Integer64;
     OriginalSize: Integer64;
     ChunkCompressedSize: Integer64;
     ChunkCompressedSize: Integer64;
-    SHA1Sum: TSHA1Digest;
+    SHA256Sum: TSHA256Digest;
     SourceTimeStamp: TFileTime;
     SourceTimeStamp: TFileTime;
     FileVersionMS, FileVersionLS: DWORD;
     FileVersionMS, FileVersionLS: DWORD;
     Flags: set of (foVersionInfoValid, foVersionInfoNotValid, foTimeStampInUTC,
     Flags: set of (foVersionInfoValid, foVersionInfoNotValid, foTimeStampInUTC,

+ 1 - 0
whatsnew.htm

@@ -83,6 +83,7 @@ For conditions of distribution and use, see <a href="files/is/license.txt">LICEN
 <ul>
 <ul>
   <li>Updated the LZMA SDK used by Inno Setup to the latest version, increasing the speed of LZMA and LZMA2 compression and decompression (respectively by 21% and 11% in a test with default settings) without changing the compression ratio. Compression memory requirements have increased by about 4%.</li>
   <li>Updated the LZMA SDK used by Inno Setup to the latest version, increasing the speed of LZMA and LZMA2 compression and decompression (respectively by 21% and 11% in a test with default settings) without changing the compression ratio. Compression memory requirements have increased by about 4%.</li>
   <li>Updated the encryption algorithm used by Inno Setup to XChaCha20 for extra security. This code is built-in: the separate ISCrypt.dll "encryption module" is no longer used and will be automatically deleted when you update.</li>
   <li>Updated the encryption algorithm used by Inno Setup to XChaCha20 for extra security. This code is built-in: the separate ISCrypt.dll "encryption module" is no longer used and will be automatically deleted when you update.</li>
+  <li>Replaced all remaining use of MD5 and SHA-1 hashes with SHA-256 hashes, without removing the MD5 and SHA-1 Pascal Scripting and ISPP support functions.</li>
   <li>Merged the Inno Setup Preprocessor documentation into the main documentation instead of being separate.</li>
   <li>Merged the Inno Setup Preprocessor documentation into the main documentation instead of being separate.</li>
   <li>Added a dark mode version of the documentation, automatically used by the Compiler IDE if a dark theme is chosen.</li>
   <li>Added a dark mode version of the documentation, automatically used by the Compiler IDE if a dark theme is chosen.</li>
   <li>Pascal Scripting changes:
   <li>Pascal Scripting changes: