Parcourir la source

Replace ArcFour with XChaCha20 which also removes iscrypt.dll use.

Todo:
-Use a single random base nonce for all files
-Remove/replace various iscrypt use in .iss scripts
-Delete iscrypt.dll on updates
-Update help & whatsnew & web
-Rename TSetupSalt/TSetupNonce?
Martijn Laan il y a 1 an
Parent
commit
d9d845ab62

+ 1 - 1
Projects/ISCmplr.dpr

@@ -33,7 +33,7 @@ uses
   Compression.bzlib in 'Src\Compression.bzlib.pas',
   Compression.bzlib in 'Src\Compression.bzlib.pas',
   Compression.LZMACompressor in 'Src\Compression.LZMACompressor.pas',
   Compression.LZMACompressor in 'Src\Compression.LZMACompressor.pas',
   Shared.FileClass in 'Src\Shared.FileClass.pas',
   Shared.FileClass in 'Src\Shared.FileClass.pas',
-  Shared.ArcFour in 'Src\Shared.ArcFour.pas',
+  ChaCha20 in '..\Components\ChaCha20.pas',
   Shared.VerInfoFunc in 'Src\Shared.VerInfoFunc.pas',
   Shared.VerInfoFunc in 'Src\Shared.VerInfoFunc.pas',
   PathFunc in '..\Components\PathFunc.pas',
   PathFunc in '..\Components\PathFunc.pas',
   Shared.CommonFunc in 'Src\Shared.CommonFunc.pas',
   Shared.CommonFunc in 'Src\Shared.CommonFunc.pas',

+ 1 - 1
Projects/ISCmplr.dproj

@@ -99,7 +99,7 @@
         <DCCReference Include="Src\Compression.bzlib.pas"/>
         <DCCReference Include="Src\Compression.bzlib.pas"/>
         <DCCReference Include="Src\Compression.LZMACompressor.pas"/>
         <DCCReference Include="Src\Compression.LZMACompressor.pas"/>
         <DCCReference Include="Src\Shared.FileClass.pas"/>
         <DCCReference Include="Src\Shared.FileClass.pas"/>
-        <DCCReference Include="Src\Shared.ArcFour.pas"/>
+        <DCCReference Include="..\Components\ChaCha20.pas"/>
         <DCCReference Include="Src\Shared.VerInfoFunc.pas"/>
         <DCCReference Include="Src\Shared.VerInfoFunc.pas"/>
         <DCCReference Include="..\Components\PathFunc.pas"/>
         <DCCReference Include="..\Components\PathFunc.pas"/>
         <DCCReference Include="Src\Shared.CommonFunc.pas"/>
         <DCCReference Include="Src\Shared.CommonFunc.pas"/>

+ 1 - 1
Projects/Setup.dpr

@@ -51,7 +51,7 @@ uses
   Setup.LoggingFunc in 'Src\Setup.LoggingFunc.pas',
   Setup.LoggingFunc in 'Src\Setup.LoggingFunc.pas',
   Setup.DebugClient in 'Src\Setup.DebugClient.pas',
   Setup.DebugClient in 'Src\Setup.DebugClient.pas',
   Shared.DebugStruct in 'Src\Shared.DebugStruct.pas',
   Shared.DebugStruct in 'Src\Shared.DebugStruct.pas',
-  Shared.ArcFour in 'Src\Shared.ArcFour.pas',
+  ChaCha20 in '..\Components\ChaCha20.pas',
   Setup.Uninstall in 'Src\Setup.Uninstall.pas',
   Setup.Uninstall in 'Src\Setup.Uninstall.pas',
   Setup.UninstallProgressForm in 'Src\Setup.UninstallProgressForm.pas' {UninstallProgressForm},
   Setup.UninstallProgressForm in 'Src\Setup.UninstallProgressForm.pas' {UninstallProgressForm},
   Setup.UninstallSharedFileForm in 'Src\Setup.UninstallSharedFileForm.pas' {UninstallSharedFileForm},
   Setup.UninstallSharedFileForm in 'Src\Setup.UninstallSharedFileForm.pas' {UninstallSharedFileForm},

+ 1 - 1
Projects/Setup.dproj

@@ -120,7 +120,7 @@
         <DCCReference Include="Src\Setup.LoggingFunc.pas"/>
         <DCCReference Include="Src\Setup.LoggingFunc.pas"/>
         <DCCReference Include="Src\Setup.DebugClient.pas"/>
         <DCCReference Include="Src\Setup.DebugClient.pas"/>
         <DCCReference Include="Src\Shared.DebugStruct.pas"/>
         <DCCReference Include="Src\Shared.DebugStruct.pas"/>
-        <DCCReference Include="Src\Shared.ArcFour.pas"/>
+        <DCCReference Include="..\Components\ChaCha20.pas"/>
         <DCCReference Include="Src\Setup.Uninstall.pas"/>
         <DCCReference Include="Src\Setup.Uninstall.pas"/>
         <DCCReference Include="Src\Setup.UninstallProgressForm.pas">
         <DCCReference Include="Src\Setup.UninstallProgressForm.pas">
             <Form>UninstallProgressForm</Form>
             <Form>UninstallProgressForm</Form>

+ 14 - 25
Projects/Src/Compiler.CompressionHandler.pas

@@ -12,7 +12,7 @@ unit Compiler.CompressionHandler;
 interface
 interface
 
 
 uses
 uses
-  SHA1, Shared.ArcFour, Shared.Int64Em, Shared.FileClass, Compression.Base,
+  SHA1, ChaCha20, Shared.Int64Em, Shared.FileClass, Compression.Base,
   Compiler.StringLists, Compiler.SetupCompiler;
   Compiler.StringLists, Compiler.SetupCompiler;
 
 
 type
 type
@@ -27,7 +27,7 @@ type
     FChunkFirstSlice: Integer;
     FChunkFirstSlice: Integer;
     FChunkStarted: Boolean;
     FChunkStarted: Boolean;
     FChunkStartOffset: Longint;
     FChunkStartOffset: Longint;
-    FCryptContext: TArcFourContext;
+    FCryptContext: TChaCha20Context;
     FCurSlice: Integer;
     FCurSlice: Integer;
     FDestFile: TFile;
     FDestFile: TFile;
     FDestFileIsDiskSlice: Boolean;
     FDestFileIsDiskSlice: Boolean;
@@ -61,7 +61,7 @@ type
 implementation
 implementation
 
 
 uses
 uses
-  SysUtils, Shared.Struct, Compiler.Messages, Compiler.HelperFunc;
+  SysUtils, Hash, Shared.Struct, Compiler.Messages, Compiler.HelperFunc;
 
 
 constructor TCompressionHandler.Create(ACompiler: TSetupCompiler;
 constructor TCompressionHandler.Create(ACompiler: TSetupCompiler;
   const InitialSliceFilename: String);
   const InitialSliceFilename: String);
@@ -189,27 +189,16 @@ procedure TCompressionHandler.NewChunk(const ACompressorClass: TCustomCompressor
   end;
   end;
 
 
   procedure InitEncryption;
   procedure InitEncryption;
-  var
-    Salt: TSetupSalt;
-    Context: TSHA1Context;
-    Hash: TSHA1Digest;
   begin
   begin
-    { Generate and write a random salt. This salt is hashed into the key to
-      prevent the same key from ever being used twice (theoretically). }
-    GenerateRandomBytes(Salt, SizeOf(Salt));
-    FDestFile.WriteBuffer(Salt, SizeOf(Salt));
-
-    { Create an SHA-1 hash of the salt plus ACryptKey, and use that as the key }
-    SHA1Init(Context);
-    SHA1Update(Context, Salt, SizeOf(Salt));
-    SHA1Update(Context, Pointer(ACryptKey)^, Length(ACryptKey)*SizeOf(ACryptKey[1]));
-    Hash := SHA1Final(Context);
-    ArcFourInit(FCryptContext, Hash, SizeOf(Hash));
-
-    { Discard first 1000 bytes of the output keystream, since according to
-      <http://en.wikipedia.org/wiki/RC4_(cipher)>, "the first few bytes of
-      output keystream are strongly non-random." }
-    ArcFourDiscard(FCryptContext, 1000);
+    { Create an SHA-256 hash of ACryptKey, and use that as the key }
+    var Key := THashSHA2.GetHashBytes(ACryptKey, SHA256);
+
+    { Generate and write a random nonce. }
+    var Nonce: TSetupNonce;
+    GenerateRandomBytes(Nonce, SizeOf(Nonce));
+    FDestFile.WriteBuffer(Nonce, SizeOf(Nonce));
+
+    XChaCha20Init(FCryptContext, Key[0], Length(Key), Nonce[0], Length(Nonce), 0);
   end;
   end;
 
 
 var
 var
@@ -221,7 +210,7 @@ begin
     start a new slice }
     start a new slice }
   MinBytesLeft := SizeOf(ZLIBID);
   MinBytesLeft := SizeOf(ZLIBID);
   if AUseEncryption then
   if AUseEncryption then
-    Inc(MinBytesLeft, SizeOf(TSetupSalt));
+    Inc(MinBytesLeft, SizeOf(TSetupNonce));
   Inc(MinBytesLeft);  { for at least one byte of data }
   Inc(MinBytesLeft);  { for at least one byte of data }
   if FSliceBytesLeft < MinBytesLeft then
   if FSliceBytesLeft < MinBytesLeft then
     NewSlice('');
     NewSlice('');
@@ -311,7 +300,7 @@ begin
         temporary buffer. }
         temporary buffer. }
       GetMem(P2, S);
       GetMem(P2, S);
       try
       try
-        ArcFourCrypt(FCryptContext, P^, P2^, S);
+        XChaCha20Crypt(FCryptContext, P^, P2^, S);
         FDestFile.WriteBuffer(P2^, S)
         FDestFile.WriteBuffer(P2^, S)
       finally
       finally
         FreeMem(P2);
         FreeMem(P2);

+ 0 - 3
Projects/Src/Compiler.Messages.pas

@@ -49,7 +49,6 @@ const
   SCompilerStatusCreateSetupFiles = 'Creating setup files';
   SCompilerStatusCreateSetupFiles = 'Creating setup files';
   SCompilerStatusSkippingCreateSetupFiles = 'Skipping creating setup files, output is disabled';
   SCompilerStatusSkippingCreateSetupFiles = 'Skipping creating setup files, output is disabled';
   SCompilerStatusCreateManifestFile = 'Creating manifest file';
   SCompilerStatusCreateManifestFile = 'Creating manifest file';
-  SCompilerStatusFilesInitEncryption = '   Initializing encryption';
   SCompilerStatusFilesCompressing = '   Compressing: %s';
   SCompilerStatusFilesCompressing = '   Compressing: %s';
   SCompilerStatusFilesCompressingVersion = '   Compressing: %s   (%u.%u.%u.%u)';
   SCompilerStatusFilesCompressingVersion = '   Compressing: %s   (%u.%u.%u.%u)';
   SCompilerStatusFilesStoring = '   Storing: %s';
   SCompilerStatusFilesStoring = '   Storing: %s';
@@ -92,8 +91,6 @@ const
   SCompilerSetup0Mismatch = 'Internal error SC1';
   SCompilerSetup0Mismatch = 'Internal error SC1';
   SCompilerMustUseDiskSpanning = 'Disk spanning must be enabled in order to create an installation larger than %d bytes in size';
   SCompilerMustUseDiskSpanning = 'Disk spanning must be enabled in order to create an installation larger than %d bytes in size';
   SCompilerCompileCodeError = 'An error occurred while trying to compile the [Code] section:' + SNewLine2 + '%s';
   SCompilerCompileCodeError = 'An error occurred while trying to compile the [Code] section:' + SNewLine2 + '%s';
-  SCompilerISCryptMissing = 'Cannot use encryption because ISCrypt.dll is missing.' + SNewLine2 +
-    'Note: This file is not installed with Inno Setup. A link to obtain it can be found on the Inno Setup web site';
   SCompilerFunctionFailedWithCode = '%s failed. Error %d: %s';
   SCompilerFunctionFailedWithCode = '%s failed. Error %d: %s';
 
 
   { [Setup] }
   { [Setup] }

+ 3 - 36
Projects/Src/Compiler.SetupCompiler.pas

@@ -202,7 +202,6 @@ type
     function FindSignToolIndexByName(const AName: String): Integer;
     function FindSignToolIndexByName(const AName: String): Integer;
     function GetLZMAExeFilename(const Allow64Bit: Boolean): String;
     function GetLZMAExeFilename(const Allow64Bit: Boolean): String;
     procedure InitBzipDLL;
     procedure InitBzipDLL;
-    procedure InitCryptDLL;
     procedure InitPreLangData(const APreLangData: TPreLangData);
     procedure InitPreLangData(const APreLangData: TPreLangData);
     procedure InitLanguageEntry(var ALanguageEntry: TSetupLanguageEntry);
     procedure InitLanguageEntry(var ALanguageEntry: TSetupLanguageEntry);
     procedure InitLZMADLL;
     procedure InitLZMADLL;
@@ -291,7 +290,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, Shared.ArcFour, SHA1,
+  Shared.FileClass, Compression.Base, Compression.Zlib, Compression.bzlib, SHA1,
   Shared.LangOptionsSectionDirectives, Shared.ResUpdateFunc, Compiler.ExeUpdateFunc,
   Shared.LangOptionsSectionDirectives, Shared.ResUpdateFunc, Compiler.ExeUpdateFunc,
 {$IFDEF STATICPREPROC}
 {$IFDEF STATICPREPROC}
   ISPP.Preprocess,
   ISPP.Preprocess,
@@ -310,7 +309,7 @@ type
   end;
   end;
 
 
 var
 var
-  ZipInitialized, BzipInitialized, LZMAInitialized, CryptInitialized: Boolean;
+  ZipInitialized, BzipInitialized, LZMAInitialized: Boolean;
   PreprocessorInitialized: Boolean;
   PreprocessorInitialized: Boolean;
   PreprocessScriptProc: TPreprocessScriptProc;
   PreprocessScriptProc: TPreprocessScriptProc;
 
 
@@ -659,20 +658,6 @@ begin
   Result := SlicesPerDisk;
   Result := SlicesPerDisk;
 end;
 end;
 
 
-procedure TSetupCompiler.InitCryptDLL;
-var
-  M: HMODULE;
-begin
-  if CryptInitialized then
-    Exit;
-  M := SafeLoadLibrary(CompilerDir + 'iscrypt.dll', SEM_NOOPENFILEERRORBOX);
-  if M = 0 then
-    AbortCompileFmt('Failed to load iscrypt.dll (%d)', [GetLastError]);
-  if not ArcFourInitFunctions(M) then
-    AbortCompile('Failed to get address of functions in iscrypt.dll');
-  CryptInitialized := True;
-end;
-
 function TSetupCompiler.FilenameToFileIndex(const AFilename: String): Integer;
 function TSetupCompiler.FilenameToFileIndex(const AFilename: String): Integer;
 begin
 begin
   if not GotPrevFilename or (PathCompare(AFilename, PrevFilename) <> 0) then begin
   if not GotPrevFilename or (PathCompare(AFilename, PrevFilename) <> 0) then begin
@@ -6633,7 +6618,7 @@ var
   ExeFile: TFile;
   ExeFile: TFile;
   LicenseText, InfoBeforeText, InfoAfterText: AnsiString;
   LicenseText, InfoBeforeText, InfoAfterText: AnsiString;
   WizardImages, WizardSmallImages: TObjectList<TCustomMemoryStream>;
   WizardImages, WizardSmallImages: TObjectList<TCustomMemoryStream>;
-  DecompressorDLL, DecryptionDLL: TMemoryStream;
+  DecompressorDLL: TMemoryStream;
 
 
   SetupLdrOffsetTable: TSetupLdrOffsetTable;
   SetupLdrOffsetTable: TSetupLdrOffsetTable;
   SizeOfExe, SizeOfHeaders: Longint;
   SizeOfExe, SizeOfHeaders: Longint;
@@ -6739,8 +6724,6 @@ var
         WriteStream(WizardSmallImages[J], W);
         WriteStream(WizardSmallImages[J], W);
       if SetupHeader.CompressMethod in [cmZip, cmBzip] then
       if SetupHeader.CompressMethod in [cmZip, cmBzip] then
         WriteStream(DecompressorDLL, W);
         WriteStream(DecompressorDLL, W);
-      if shEncryptionUsed in SetupHeader.Options then
-        WriteStream(DecryptionDLL, W);
 
 
       W.Finish;
       W.Finish;
     finally
     finally
@@ -6908,12 +6891,6 @@ var
     ChunkCompressed := False;  { avoid warning }
     ChunkCompressed := False;  { avoid warning }
     CH := TCompressionHandler.Create(Self, FirstDestFile);
     CH := TCompressionHandler.Create(Self, FirstDestFile);
     try
     try
-      { If encryption is used, load the encryption DLL }
-      if shEncryptionUsed in SetupHeader.Options then begin
-        AddStatus(SCompilerStatusFilesInitEncryption);
-        InitCryptDLL;
-      end;
-
       if DiskSpanning then begin
       if DiskSpanning then begin
         if not CH.ReserveBytesOnSlice(BytesToReserveOnFirstDisk) then
         if not CH.ReserveBytesOnSlice(BytesToReserveOnFirstDisk) then
           AbortCompile(SCompilerNotEnoughSpaceOnFirstDisk);
           AbortCompile(SCompilerNotEnoughSpaceOnFirstDisk);
@@ -7356,7 +7333,6 @@ begin
   WizardSmallImages := nil;
   WizardSmallImages := nil;
   SetupE32 := nil;
   SetupE32 := nil;
   DecompressorDLL := nil;
   DecompressorDLL := nil;
-  DecryptionDLL := nil;
 
 
   try
   try
     Finalize(SetupHeader);
     Finalize(SetupHeader);
@@ -7870,14 +7846,6 @@ begin
         end;
         end;
     end;
     end;
 
 
-    { Read decryption DLL }
-    if shEncryptionUsed in SetupHeader.Options then begin
-      AddStatus(Format(SCompilerStatusReadingFile, ['iscrypt.dll']));
-      if not NewFileExists(CompilerDir + 'iscrypt.dll') then
-        AbortCompile(SCompilerISCryptMissing);
-      DecryptionDLL := CreateMemoryStreamFromFile(CompilerDir + 'iscrypt.dll');
-    end;
-
     { Add default types if necessary }
     { Add default types if necessary }
     if (ComponentEntries.Count > 0) and (TypeEntries.Count = 0) then begin
     if (ComponentEntries.Count > 0) and (TypeEntries.Count = 0) then begin
       AddDefaultSetupType(DefaultTypeEntryNames[0], [], ttDefaultFull);
       AddDefaultSetupType(DefaultTypeEntryNames[0], [], ttDefaultFull);
@@ -8057,7 +8025,6 @@ begin
     UsedUserAreas.Clear;
     UsedUserAreas.Clear;
     WarningsList.Clear;
     WarningsList.Clear;
     { Free all the data }
     { Free all the data }
-    DecryptionDLL.Free;
     DecompressorDLL.Free;
     DecompressorDLL.Free;
     SetupE32.Free;
     SetupE32.Free;
     WizardSmallImages.Free;
     WizardSmallImages.Free;

+ 0 - 6
Projects/Src/IDE.HelperFunc.pas

@@ -37,7 +37,6 @@ procedure AddFileToRecentDocs(const Filename: String);
 function GenerateGuid: String;
 function GenerateGuid: String;
 function ISPPInstalled: Boolean;
 function ISPPInstalled: Boolean;
 function IsISPPBuiltins(const Filename: String): Boolean;
 function IsISPPBuiltins(const Filename: String): Boolean;
-function ISCryptInstalled: Boolean;
 function WindowsVersionAtLeast(const AMajor, AMinor: Byte; const ABuild: Word = 0): Boolean;
 function WindowsVersionAtLeast(const AMajor, AMinor: Byte; const ABuild: Word = 0): Boolean;
 function IsWindows10: Boolean;
 function IsWindows10: Boolean;
 function IsWindows11: Boolean;
 function IsWindows11: Boolean;
@@ -243,11 +242,6 @@ begin
   Result := PathCompare(PathExtractName(Filename), 'ISPPBuiltins.iss') = 0;
   Result := PathCompare(PathExtractName(Filename), 'ISPPBuiltins.iss') = 0;
 end;
 end;
 
 
-function ISCryptInstalled: Boolean;
-begin
-  Result := NewFileExists(PathExtractPath(NewParamStr(0)) + 'iscrypt.dll');
-end;
-
 var
 var
   WindowsVersion: Cardinal;
   WindowsVersion: Cardinal;
 
 

+ 1 - 2
Projects/Src/IDE.Wizard.WizardForm.pas

@@ -373,7 +373,6 @@ begin
 
 
   { Compiler }
   { Compiler }
   OutputBaseFileNameEdit.Text := 'mysetup';
   OutputBaseFileNameEdit.Text := 'mysetup';
-  EncryptionCheck.Visible := ISCryptInstalled;
   EncryptionCheck.Checked := True;
   EncryptionCheck.Checked := True;
   EncryptionCheck.Enabled := False;
   EncryptionCheck.Enabled := False;
 
 
@@ -1053,7 +1052,7 @@ begin
       Setup := Setup + 'SetupIconFile=' + SetupIconFileEdit.Text + SNewLine;
       Setup := Setup + 'SetupIconFile=' + SetupIconFileEdit.Text + SNewLine;
     if PasswordEdit.Text <> '' then begin
     if PasswordEdit.Text <> '' then begin
       Setup := Setup + 'Password=' + PasswordEdit.Text + SNewLine;
       Setup := Setup + 'Password=' + PasswordEdit.Text + SNewLine;
-      if ISCryptInstalled and EncryptionCheck.Checked then
+      if EncryptionCheck.Checked then
         Setup := Setup + 'Encryption=yes' + SNewLine;
         Setup := Setup + 'Encryption=yes' + SNewLine;
     end;
     end;
 
 

+ 13 - 22
Projects/Src/Setup.FileExtractor.pas

@@ -13,7 +13,7 @@ interface
 
 
 uses
 uses
   Windows, SysUtils, Shared.Int64Em, Shared.FileClass, Compression.Base,
   Windows, SysUtils, Shared.Int64Em, Shared.FileClass, Compression.Base,
-  Shared.Struct, Shared.ArcFour;
+  Shared.Struct, ChaCha20;
 
 
 type
 type
   TExtractorProgressProc = procedure(Bytes: Cardinal);
   TExtractorProgressProc = procedure(Bytes: Cardinal);
@@ -27,7 +27,7 @@ type
     FChunkBytesLeft, FChunkDecompressedBytesRead: Integer64;
     FChunkBytesLeft, FChunkDecompressedBytesRead: Integer64;
     FNeedReset: Boolean;
     FNeedReset: Boolean;
     FChunkCompressed, FChunkEncrypted: Boolean;
     FChunkCompressed, FChunkEncrypted: Boolean;
-    FCryptContext: TArcFourContext;
+    FCryptContext: TChaCha20Context;
     FCryptKey: String;
     FCryptKey: String;
     FEntered: Integer;
     FEntered: Integer;
     procedure DecompressBytes(var Buffer; Count: Cardinal);
     procedure DecompressBytes(var Buffer; Count: Cardinal);
@@ -50,8 +50,8 @@ procedure FreeFileExtractor;
 implementation
 implementation
 
 
 uses
 uses
-  PathFunc, Shared.CommonFunc, Setup.MainFunc, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs,
-  Setup.InstFunc, Compression.Zlib, Compression.bzlib,
+  Hash, PathFunc, Shared.CommonFunc, Setup.MainFunc, SetupLdrAndSetup.Messages,
+  Shared.SetupMessageIDs, Setup.InstFunc, Compression.Zlib, Compression.bzlib,
   Compression.LZMADecompressor, SHA1, Setup.LoggingFunc, Setup.NewDiskForm;
   Compression.LZMADecompressor, SHA1, Setup.LoggingFunc, Setup.NewDiskForm;
 
 
 var
 var
@@ -189,25 +189,16 @@ procedure TFileExtractor.SeekTo(const FL: TSetupFileLocationEntry;
   const ProgressProc: TExtractorProgressProc);
   const ProgressProc: TExtractorProgressProc);
 
 
   procedure InitDecryption;
   procedure InitDecryption;
-  var
-    Salt: TSetupSalt;
-    Context: TSHA1Context;
-    Hash: TSHA1Digest;
   begin
   begin
-    { Read the salt }
-    if FSourceF.Read(Salt, SizeOf(Salt)) <> SizeOf(Salt) then
-      SourceIsCorrupted('Failed to read salt');
+    { Read the nonce }
+    var Nonce: TSetupNonce;
+    if FSourceF.Read(Nonce, SizeOf(Nonce)) <> SizeOf(Nonce) then
+      SourceIsCorrupted('Failed to read nonce');
 
 
-    { Initialize the key, which is the SHA-1 hash of the salt plus FCryptKey }
-    SHA1Init(Context);
-    SHA1Update(Context, Salt, SizeOf(Salt));
-    SHA1Update(Context, Pointer(FCryptKey)^, Length(FCryptKey)*SizeOf(FCryptKey[1]));
-    Hash := SHA1Final(Context);
-    ArcFourInit(FCryptContext, Hash, SizeOf(Hash));
-
-    { The compiler discards the first 1000 bytes for extra security,
-      so we must as well }
-    ArcFourDiscard(FCryptContext, 1000);
+    { Initialize the key, which is the SHA-256 hash of FCryptKey }
+    var Key := THashSHA2.GetHashBytes(FCryptKey, SHA256);
+
+    XChaCha20Init(FCryptContext, Key[0], Length(Key), Nonce[0], Length(Nonce), 0);
   end;
   end;
 
 
   procedure Discard(Count: Integer64);
   procedure Discard(Count: Integer64);
@@ -302,7 +293,7 @@ begin
 
 
     { Decrypt the data after reading from the file }
     { Decrypt the data after reading from the file }
     if FChunkEncrypted then
     if FChunkEncrypted then
-      ArcFourCrypt(FCryptContext, Buffer^, Buffer^, Res);
+      ChaCha20Crypt(FCryptContext, Buffer^, Buffer^, Res);
 
 
     if Left = Res then
     if Left = Res then
       Break
       Break

+ 3 - 29
Projects/Src/Setup.MainFunc.pas

@@ -241,7 +241,7 @@ uses
   SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.Install, SetupLdrAndSetup.InstFunc,
   SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.Install, SetupLdrAndSetup.InstFunc,
   Setup.InstFunc, SetupLdrAndSetup.RedirFunc, PathFunc,
   Setup.InstFunc, SetupLdrAndSetup.RedirFunc, PathFunc,
   Compression.Base, Compression.Zlib, Compression.bzlib, Compression.LZMADecompressor,
   Compression.Base, Compression.Zlib, Compression.bzlib, Compression.LZMADecompressor,
-  Shared.ArcFour, Shared.SetupEntFunc, Setup.SelectLanguageForm,
+  Shared.SetupEntFunc, Setup.SelectLanguageForm,
   Setup.WizardForm, Setup.DebugClient, Shared.VerInfoFunc, Setup.FileExtractor,
   Setup.WizardForm, Setup.DebugClient, Shared.VerInfoFunc, Setup.FileExtractor,
   Shared.FileClass, Setup.LoggingFunc, SHA1, ActiveX,
   Shared.FileClass, Setup.LoggingFunc, SHA1, ActiveX,
   SimpleExpression, Setup.Helper, Setup.SpawnClient, Setup.SpawnServer,
   SimpleExpression, Setup.Helper, Setup.SpawnClient, Setup.SpawnServer,
@@ -2543,7 +2543,7 @@ procedure InitializeSetup;
 { Initializes various vars used by the setup. This is called in the project
 { Initializes various vars used by the setup. This is called in the project
   source. }
   source. }
 var
 var
-  DecompressorDLL, DecryptDLL: TMemoryStream;
+  DecompressorDLL: TMemoryStream;
 
 
   function ExtractLongWord(var S: String): LongWord;
   function ExtractLongWord(var S: String): LongWord;
   var
   var
@@ -2635,20 +2635,6 @@ var
     end;
     end;
   end;
   end;
 
 
-  procedure LoadDecryptDLL;
-  var
-    Filename: String;
-  begin
-    Filename := AddBackslash(TempInstallDir) + '_isetup\_iscrypt.dll';
-    SaveStreamToTempFile(DecryptDLL, Filename);
-    FreeAndNil(DecryptDLL);
-    DecryptDLLHandle := SafeLoadLibrary(Filename, SEM_NOOPENFILEERRORBOX);
-    if DecryptDLLHandle = 0 then
-      InternalError(Format('Failed to load DLL "%s"', [Filename]));
-    if not ArcFourInitFunctions(DecryptDLLHandle) then
-      InternalError('ISCryptInitFunctions failed');
-  end;
-
 var
 var
   Reader: TCompressedBlockReader;
   Reader: TCompressedBlockReader;
 
 
@@ -3161,9 +3147,7 @@ begin
         ReadEntries(seUninstallRun, SetupHeader.NumUninstallRunEntries, SizeOf(TSetupRunEntry),
         ReadEntries(seUninstallRun, SetupHeader.NumUninstallRunEntries, SizeOf(TSetupRunEntry),
           Integer(@PSetupRunEntry(nil).MinVersion),
           Integer(@PSetupRunEntry(nil).MinVersion),
           Integer(@PSetupRunEntry(nil).OnlyBelowVersion));
           Integer(@PSetupRunEntry(nil).OnlyBelowVersion));
-
-        { Wizard image }
-
+        { Wizard images }
         Reader.Read(N, SizeOf(LongInt));
         Reader.Read(N, SizeOf(LongInt));
         for I := 0 to N-1 do
         for I := 0 to N-1 do
           WizardImages.Add(ReadWizardImage(Reader));
           WizardImages.Add(ReadWizardImage(Reader));
@@ -3176,12 +3160,6 @@ begin
           DecompressorDLL := TMemoryStream.Create;
           DecompressorDLL := TMemoryStream.Create;
           ReadFileIntoStream(DecompressorDLL, Reader);
           ReadFileIntoStream(DecompressorDLL, Reader);
         end;
         end;
-        { Decryption DLL }
-        DecryptDLL := nil;
-        if shEncryptionUsed in SetupHeader.Options then begin
-          DecryptDLL := TMemoryStream.Create;
-          ReadFileIntoStream(DecryptDLL, Reader);
-        end;
       finally
       finally
         Reader.Free;
         Reader.Free;
       end;
       end;
@@ -3265,10 +3243,6 @@ begin
   if SetupHeader.CompressMethod in [cmZip, cmBzip] then
   if SetupHeader.CompressMethod in [cmZip, cmBzip] then
     LoadDecompressorDLL;
     LoadDecompressorDLL;
 
 
-  { Extract "_iscrypt.dll" to TempInstallDir, and load it }
-  if shEncryptionUsed in SetupHeader.Options then
-    LoadDecryptDLL;
-
   { Start RestartManager session }
   { Start RestartManager session }
   if InitCloseApplications or
   if InitCloseApplications or
      ((shCloseApplications in SetupHeader.Options) and not InitNoCloseApplications) then begin
      ((shCloseApplications in SetupHeader.Options) and not InitNoCloseApplications) then begin

+ 0 - 74
Projects/Src/Shared.ArcFour.pas

@@ -1,74 +0,0 @@
-unit Shared.ArcFour;
-
-{
-  Inno Setup
-  Copyright (C) 1997-2004 Jordan Russell
-  Portions by Martijn Laan
-  For conditions of distribution and use, see LICENSE.TXT.
-
-  Interface to ISCrypt.dll (ARCFOUR encryption/decryption)
-}
-
-interface
-
-uses
-  Windows;
-
-type
-  TArcFourContext = record
-    state: array[0..255] of Byte;
-    x, y: Byte;
-  end;
-
-function ArcFourInitFunctions(Module: HMODULE): Boolean;
-procedure ArcFourInit(var Context: TArcFourContext; const Key;
-  KeyLength: Cardinal);
-procedure ArcFourCrypt(var Context: TArcFourContext; const InBuffer;
-  var OutBuffer; Length: Cardinal);
-procedure ArcFourDiscard(var Context: TArcFourContext; Bytes: Cardinal);
-
-implementation
-
-var
-  _ISCryptGetVersion: function: Integer; stdcall;
-  _ArcFourInit: procedure(var context: TArcFourContext; const key;
-    key_length: Cardinal); stdcall;
-  _ArcFourCrypt: procedure(var context: TArcFourContext; const in_buffer;
-    var out_buffer; length: Cardinal); stdcall;
-
-function ArcFourInitFunctions(Module: HMODULE): Boolean;
-begin
-  _ISCryptGetVersion := GetProcAddress(Module, 'ISCryptGetVersion');
-  _ArcFourInit := GetProcAddress(Module, 'ArcFourInit');
-  _ArcFourCrypt := GetProcAddress(Module, 'ArcFourCrypt');
-  if Assigned(_ISCryptGetVersion) and Assigned(_ArcFourInit) and
-     Assigned(_ArcFourCrypt) then begin
-    { Verify that the DLL's version is what we expect }
-    Result := (_ISCryptGetVersion = 1);
-  end
-  else begin
-    Result := False;
-    _ISCryptGetVersion := nil;
-    _ArcFourInit := nil;
-    _ArcFourCrypt := nil;
-  end
-end;
-
-procedure ArcFourInit(var Context: TArcFourContext; const Key;
-  KeyLength: Cardinal);
-begin
-  _ArcFourInit(Context, Key, KeyLength);
-end;
-
-procedure ArcFourCrypt(var Context: TArcFourContext; const InBuffer;
-  var OutBuffer; Length: Cardinal);
-begin
-  _ArcFourCrypt(Context, InBuffer, OutBuffer, Length);
-end;
-
-procedure ArcFourDiscard(var Context: TArcFourContext; Bytes: Cardinal);
-begin
-  _ArcFourCrypt(Context, Pointer(nil)^, Pointer(nil)^, Bytes);
-end;
-
-end.

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

@@ -33,7 +33,7 @@ const
     this file it's recommended you change SetupID. Any change will do (like
     this file it's recommended you change SetupID. Any change will do (like
     changing the letters or numbers), as long as your format is
     changing the letters or numbers), as long as your format is
     unrecognizable by the standard Inno Setup. }
     unrecognizable by the standard Inno Setup. }
-  SetupID: TSetupID = 'Inno Setup Setup Data (6.3.0)';
+  SetupID: TSetupID = 'Inno Setup Setup Data (6.4.0)';
   UninstallLogID: array[Boolean] of TUninstallLogID =
   UninstallLogID: array[Boolean] of TUninstallLogID =
     ('Inno Setup Uninstall Log (b)', 'Inno Setup Uninstall Log (b) 64-bit');
     ('Inno Setup Uninstall Log (b)', 'Inno Setup Uninstall Log (b) 64-bit');
   MessagesHdrID: TMessagesHdrID = 'Inno Setup Messages (6.0.0) (u)';
   MessagesHdrID: TMessagesHdrID = 'Inno Setup Messages (6.0.0) (u)';
@@ -69,6 +69,7 @@ type
   TSetupLanguageDetectionMethod = (ldUILanguage, ldLocale, ldNone);
   TSetupLanguageDetectionMethod = (ldUILanguage, ldLocale, ldNone);
   TSetupCompressMethod = (cmStored, cmZip, cmBzip, cmLZMA, cmLZMA2);
   TSetupCompressMethod = (cmStored, cmZip, cmBzip, cmLZMA, cmLZMA2);
   TSetupSalt = array[0..7] of Byte;
   TSetupSalt = array[0..7] of Byte;
+  TSetupNonce = array[0..23] of Byte;
   TSetupProcessorArchitecture = (paUnknown, paX86, paX64, paArm32, paArm64);
   TSetupProcessorArchitecture = (paUnknown, paX86, paX64, paArm32, paArm64);
   TSetupProcessorArchitectures = set of TSetupProcessorArchitecture;
   TSetupProcessorArchitectures = set of TSetupProcessorArchitecture;
   TSetupDisablePage = (dpAuto, dpNo, dpYes);
   TSetupDisablePage = (dpAuto, dpNo, dpYes);