📄 msgcipher.pas
字号:
Move(FFeedback^, FBuffer^, FBufSize);
Move(FVector^, FFeedback^, FBufSize);
end;
procedure TCipher.Protect;
begin
SetFlag(0, False);
Initialized := False;
// a Crypto Fanatican say: this is better !!
FillChar(FVector^, FBufSize, $AA);
FillChar(FFeedback^, FBufSize, $AA);
FillChar(FBuffer^, FBufSize, $AA);
FillChar(FUser^, FUserSize, $AA);
FillChar(FVector^, FBufSize, $55);
FillChar(FFeedback^, FBufSize, $55);
FillChar(FBuffer^, FBufSize, $55);
FillChar(FUser^, FUserSize, $55);
FillChar(FVector^, FBufSize, $FF);
FillChar(FFeedback^, FBufSize, $FF);
FillChar(FBuffer^, FBufSize, 0);
FillChar(FUser^, FUserSize, 0);
end;
function TCipher.GetHash: THash;
begin
if not IsObject(FHash, THash) then
begin
if FHashClass = nil then FHashClass := DefaultHashClass;
FHash := FHashClass.Create(nil);
FHash.AddRef;
end;
Result := FHash;
end;
procedure TCipher.SetHashClass(Value: THashClass);
begin
if Value <> FHashClass then
begin
FHash.Release;
FHash := nil;
FHashClass := Value;
if FHashClass = nil then FHashClass := DefaultHashClass;
end;
end;
procedure TCipher.InternalCodeStream(Source, Dest: TStream; DataSize: Integer; Encode: Boolean);
const
maxBufSize = 1024 * 4;
var
Buf: PChar;
SPos: Integer;
DPos: Integer;
Len: Integer;
Proc: procedure(const Source; var Dest; DataSize: Integer) of object;
Size: Integer;
begin
if Source = nil then Exit;
if Encode or (Mode in [cmCBCMAC, cmCTSMAC, cmCFBMAC]) then Proc := EncodeBuffer
else Proc := DecodeBuffer;
if Dest = nil then Dest := Source;
if DataSize < 0 then
begin
DataSize := Source.Size;
Source.Position := 0;
end;
Buf := nil;
Size := DataSize;
DoProgress(Self, 0, Size);
try
Buf := AllocMem(maxBufSize);
DPos := Dest.Position;
SPos := Source.Position;
if Mode in [cmCTSMAC, cmCBCMAC, cmCFBMAC] then
begin
while DataSize > 0 do
begin
Len := DataSize;
if Len > maxBufSize then Len := maxBufSize;
Len := Source.Read(Buf^, Len);
if Len <= 0 then Break;
Proc(Buf^, Buf^, Len);
Dec(DataSize, Len);
DoProgress(Self, Size - DataSize, Size);
end;
end else
while DataSize > 0 do
begin
Source.Position := SPos;
Len := DataSize;
if Len > maxBufSize then Len := maxBufSize;
Len := Source.Read(Buf^, Len);
SPos := Source.Position;
if Len <= 0 then Break;
Proc(Buf^, Buf^, Len);
Dest.Position := DPos;
Dest.Write(Buf^, Len);
DPos := Dest.Position;
Dec(DataSize, Len);
DoProgress(Self, Size - DataSize, Size);
end;
finally
DoProgress(Self, 0, 0);
ReallocMem(Buf, 0);
end;
end;
procedure TCipher.InternalCodeFile(const Source, Dest: String; Encode: Boolean);
var
S,D: TFileStream;
begin
S := nil;
D := nil;
try
if Mode in [cmCBCMAC, cmCTSMAC, cmCFBMAC] then
begin
S := TFileStream.Create(Source, fmOpenRead or fmShareDenyNone);
D := S;
end else
if (AnsiCompareText(Source, Dest) <> 0) and (Trim(Dest) <> '') then
begin
S := TFileStream.Create(Source, fmOpenRead or fmShareDenyNone);
D := TFileStream.Create(Dest, fmCreate);
end else
begin
S := TFileStream.Create(Source, fmOpenReadWrite);
D := S;
end;
InternalCodeStream(S, D, -1, Encode);
finally
S.Free;
if S <> D then
begin
{$IFDEF VER_D3H}
D.Size := D.Position;
{$ENDIF}
D.Free;
end;
end;
end;
procedure TCipher.EncodeStream(const Source, Dest: TStream; DataSize: Integer);
begin
InternalCodeStream(Source, Dest, DataSize, True);
end;
procedure TCipher.DecodeStream(const Source, Dest: TStream; DataSize: Integer);
begin
InternalCodeStream(Source, Dest, DataSize, False);
end;
procedure TCipher.EncodeFile(const Source, Dest: String);
begin
InternalCodeFile(Source, Dest, True);
end;
procedure TCipher.DecodeFile(const Source, Dest: String);
begin
InternalCodeFile(Source, Dest, False);
end;
function TCipher.EncodeString(const Source: String): String;
begin
SetLength(Result, Length(Source));
EncodeBuffer(PChar(Source)^, PChar(Result)^, Length(Source));
if Mode in [cmCBCMAC, cmCTSMAC, cmCFBMAC] then Result := '';
end;
function TCipher.DecodeString(const Source: String): String;
begin
SetLength(Result, Length(Source));
DecodeBuffer(PChar(Source)^, PChar(Result)^, Length(Source));
if Mode in [cmCBCMAC, cmCTSMAC, cmCFBMAC] then Result := '';
end;
procedure TCipher.EncodeBuffer(const Source; var Dest; DataSize: Integer);
var
S,D,F: PByte;
begin
if not Initialized then
RaiseCipherException(errNotInitialized, Format(sNotInitialized, [ClassName]));
S := @Source;
D := @Dest;
case FMode of
cmECB:
begin
if S <> D then Move(S^, D^, DataSize);
while DataSize >= FBufSize do
begin
Encode(D);
Inc(D, FBufSize);
Dec(DataSize, FBufSize);
end;
if DataSize > 0 then
begin
Move(D^, FBuffer^, DataSize);
Encode(FBuffer);
Move(FBuffer^, D^, DataSize);
end;
end;
cmCTS:
begin
while DataSize >= FBufSize do
begin
XORBuffers(S, FFeedback, FBufSize, D);
Encode(D);
XORBuffers(D, FFeedback, FBufSize, FFeedback);
Inc(S, FBufSize);
Inc(D, FBufSize);
Dec(DataSize, FBufSize);
end;
if DataSize > 0 then
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
XORBuffers(S, FBuffer, DataSize, D);
XORBuffers(FBuffer, FFeedback, FBufSize, FFeedback);
end;
end;
cmCBC:
begin
F := FFeedback;
while DataSize >= FBufSize do
begin
XORBuffers(S, F, FBufSize, D);
Encode(D);
F := D;
Inc(S, FBufSize);
Inc(D, FBufSize);
Dec(DataSize, FBufSize);
end;
Move(F^, FFeedback^, FBufSize);
if DataSize > 0 then
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
XORBuffers(S, FBuffer, DataSize, D);
XORBuffers(FBuffer, FFeedback, FBufSize, FFeedback);
end;
end;
cmCFB:
while DataSize > 0 do
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
D^ := S^ xor PByte(FBuffer)^;
Move(PByteArray(FFeedback)[1], FFeedback^, FBufSize-1);
PByteArray(FFeedback)[FBufSize-1] := D^;
Inc(D);
Inc(S);
Dec(DataSize);
end;
cmOFB:
while DataSize > 0 do
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
D^ := S^ xor PByte(FBuffer)^;
Move(PByteArray(FFeedback)[1], FFeedback^, FBufSize-1);
PByteArray(FFeedback)[FBufSize-1] := PByte(FBuffer)^;
Inc(D);
Inc(S);
Dec(DataSize);
end;
cmCTSMAC:
begin
while DataSize >= FBufSize do
begin
XORBuffers(S, FFeedback, FBufSize, FBuffer);
Encode(FBuffer);
XORBuffers(FBuffer, FFeedback, FBufSize, FFeedback);
Inc(S, FBufSize);
Dec(DataSize, FBufSize);
end;
if DataSize > 0 then
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
XORBuffers(FBuffer, FFeedback, FBufSize, FFeedback);
end;
end;
cmCBCMAC:
begin
while DataSize >= FBufSize do
begin
XORBuffers(S, FFeedback, FBufSize, FBuffer);
Encode(FBuffer);
Move(FBuffer^, FFeedback^, FBufSize);
Inc(S, FBufSize);
Dec(DataSize, FBufSize);
end;
if DataSize > 0 then
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
XORBuffers(FBuffer, FFeedback, FBufSize, FFeedback);
end;
end;
cmCFBMAC:
while DataSize > 0 do
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
Move(PByteArray(FFeedback)[1], FFeedback^, FBufSize-1);
PByteArray(FFeedback)[FBufSize-1] := S^ xor PByte(FBuffer)^;
Inc(S);
Dec(DataSize);
end;
end;
end;
procedure TCipher.DecodeBuffer(const Source; var Dest; DataSize: Integer);
var
S,D,F,B: PByte;
begin
if not Initialized then
RaiseCipherException(errNotInitialized, Format(sNotInitialized, [ClassName]));
S := @Source;
D := @Dest;
case FMode of
cmECB:
begin
if S <> D then Move(S^, D^, DataSize);
while DataSize >= FBufSize do
begin
Decode(D);
Inc(D, FBufSize);
Dec(DataSize, FBufSize);
end;
if DataSize > 0 then
begin
Move(D^, FBuffer^, DataSize);
Encode(FBuffer);
Move(FBuffer^, D^, DataSize);
end;
end;
cmCTS:
begin
if S <> D then Move(S^, D^, DataSize);
F := FFeedback;
B := FBuffer;
while DataSize >= FBufSize do
begin
XORBuffers(D, F, FBufSize, B);
Decode(D);
XORBuffers(D, F, FBufSize, D);
S := B;
B := F;
F := S;
Inc(D, FBufSize);
Dec(DataSize, FBufSize);
end;
if F <> FFeedback then Move(F^, FFeedback^, FBufSize);
if DataSize > 0 then
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
XORBuffers(FBuffer, D, DataSize, D);
XORBuffers(FBuffer, FFeedback, FBufSize, FFeedback);
end;
end;
cmCBC:
begin
if S <> D then Move(S^, D^, DataSize);
F := FFeedback;
B := FBuffer;
while DataSize >= FBufSize do
begin
Move(D^, B^, FBufSize);
Decode(D);
XORBuffers(F, D, FBufSize, D);
S := B;
B := F;
F := S;
Inc(D, FBufSize);
Dec(DataSize, FBufSize);
end;
if F <> FFeedback then Move(F^, FFeedback^, FBufSize);
if DataSize > 0 then
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
XORBuffers(D, FBuffer, DataSize, D);
XORBuffers(FBuffer, FFeedback, FBufSize, FFeedback);
end;
end;
cmCFB:
while DataSize > 0 do
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
Move(PByteArray(FFeedback)[1], FFeedback^, FBufSize-1);
PByteArray(FFeedback)[FBufSize-1] := S^;
D^ := S^ xor PByte(FBuffer)^;
Inc(D);
Inc(S);
Dec(DataSize);
end;
cmOFB:
while DataSize > 0 do
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
D^ := S^ xor PByte(FBuffer)^;
Move(PByteArray(FFeedback)[1], FFeedback^, FBufSize-1);
PByteArray(FFeedback)[FBufSize-1] := PByte(FBuffer)^;
Inc(D);
Inc(S);
Dec(DataSize);
end;
cmCTSMAC, cmCBCMAC, cmCFBMAC:
begin
EncodeBuffer(Source, Dest, DataSize);
Exit;
end;
end;
end;
procedure TCipher.CodeInit(Action: TPAction);
begin
if not Initialized then
RaiseCipherException(errNotInitialized, Format(sNotInitialized, [ClassName]));
{ if (Mode in [cmCBCMAC, cmCTSMAC, cmCFBMAC]) <> (Action = paCalc) then
RaiseCipherException(errCantCalc, Format(sCantCalc, [ClassName]));}
if Action <> paCalc then
if Action <> paWipe then Done
else RndXORBuffer(RndTimeSeed, FFeedback^, FBufSize);
inherited CodeInit(Action);
end;
procedure TCipher.CodeDone(Action: TPAction);
begin
inherited CodeDone(Action);
if Action <> paCalc then
if Action <> paWipe then Done
else RndXORBuffer(RndTimeSeed, FFeedback^, FBufSize);
end;
procedure TCipher.CodeBuf(var Buffer; const BufferSize: Integer; Action: TPAction);
begin
if Action = paDecode then
begin
if Action in Actions then
DecodeBuffer(Buffer, Buffer, BufferSize);
inherited CodeBuf(Buffer, BufferSize, Action);
end else
begin
inherited CodeBuf(Buffer, BufferSize, Action);
if Action in Actions then
EncodeBuffer(Buffer, Buffer, BufferSize);
end;
end;
function TCipher.CalcMAC(Format: Integer): String;
var
B: PByteArray;
begin
if Mode in [cmECB, cmOFB] then
RaiseCipherException(errInvalidMACMode, sInvalidMACMode);
Done;
B := AllocMem(FBufSize);
try
Move(FBuffer^, B^, FBufSize);
EncodeBuffer(B^, B^, FBufSize);
SetLength(Result, FBufSize);
Move(FFeedback^, PChar(Result)^, FBufSize);
if Protection <> nil then Result := Protection.CodeString(Result, paScramble, Format)
else Result := StrToFormat(PChar(Result), Length(Result), Format);
finally
ReallocMem(B, 0);
Done;
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -