procedure InitDecryption;
var
Salt: TSetupSalt;
MD5Context: TMD5Context;
MD5Hash: TMD5Digest;
SHA1Context: TSHA1Context;
SHA1Hash: TSHA1Digest;
begin
{ Read the salt }
if FSourceF.Read(Salt, SizeOf(Salt)) <> SizeOf(Salt) then
SourceIsCorrupted;
if (Ver >= 5309) then
begin
{ Initialize the key, which is the MD5 hash of the salt plus FCryptKey }
SHA1Init(SHA1Context);
SHA1Update(SHA1Context, Salt, SizeOf(Salt));
SHA1Update(SHA1Context, Pointer(FCryptKey)^, Length(FCryptKey));
SHA1Hash := SHA1Final(SHA1Context);
ArcFourInit(FCryptContext, SHA1Hash, SizeOf(SHA1Hash));
end else
begin
{ Initialize the key, which is the MD5 hash of the salt plus FCryptKey }
MD5Init(MD5Context);
MD5Update(MD5Context, Salt, SizeOf(Salt));
MD5Update(MD5Context, Pointer(FCryptKey)^, Length(FCryptKey));
MD5Hash := MD5Final(MD5Context);
ArcFourInit(FCryptContext, MD5Hash, SizeOf(MD5Hash));
end;
function TFileExtractor.ReadProc(var Buf; Count: Longint): Longint;
var
Buffer: Pointer;
Left, Res: Cardinal;
begin
Buffer := @Buf;
Left := Count;
if (FChunkBytesLeft.Hi = 0) and (FChunkBytesLeft.Lo < Left) then
Left := FChunkBytesLeft.Lo;
Result := Left;
while Left <> 0 do begin
Res := FSourceF.Read(Buffer^, Left);
Dec64(FChunkBytesLeft, Res);
{ Decrypt the data after reading from the file }
if FChunkEncrypted then
ArcFourCrypt(FCryptContext, Buffer^, Buffer^, Res);
if Left = Res then
Break
else begin
Dec(Left, Res);
Inc(Longint(Buffer), Res);
{ Go to next disk }
if FOpenedSlice >= FChunkLastSlice then
{ Already on the last slice, so the file must be corrupted... }
SourceIsCorrupted;
OpenSlice(FOpenedSlice + 1);
end;
end;
end;