snmpsend.pas - added Privacy encryption support. Supported are DES, 3DES and AES.

git-svn-id: https://svn.code.sf.net/p/synalist/code/trunk@142 7c85be65-684b-0410-a082-b2ed4fbef004
This commit is contained in:
geby 2011-05-05 08:14:14 +00:00
parent 66ac5c3977
commit 7bfac2f4b1
3 changed files with 227 additions and 48 deletions

View File

@ -1,9 +1,9 @@
{==============================================================================|
| Project : Ararat Synapse | 003.000.010 |
| Project : Ararat Synapse | 004.000.000 |
|==============================================================================|
| Content: SNMP client |
|==============================================================================|
| Copyright (c)1999-2010, Lukas Gebauer |
| Copyright (c)1999-2011, Lukas Gebauer |
| All rights reserved. |
| |
| Redistribution and use in source and binary forms, with or without |
@ -33,7 +33,7 @@
| DAMAGE. |
|==============================================================================|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
| Portions created by Lukas Gebauer are Copyright (c)2000-2010. |
| Portions created by Lukas Gebauer are Copyright (c)2000-2011. |
| All Rights Reserved. |
|==============================================================================|
| Contributor(s): |
@ -45,9 +45,12 @@
{:@abstract(SNMP client)
Supports SNMPv1 include traps, SNMPv2c and SNMPv3 include authorization
(encryption not yet supported!)
and privacy encryption.
Used RFC: RFC-1157, RFC-1901, RFC-3412, RFC-3414, RFC-3416
Used RFC: RFC-1157, RFC-1901, RFC-3412, RFC-3414, RFC-3416, RFC-3826
Supported Authorization hashes: MD5, SHA1
Supported Privacy encryptions: DES, 3DES, AES
}
{$IFDEF FPC}
@ -67,7 +70,7 @@ interface
uses
Classes, SysUtils,
blcksock, synautil, asn1util, synaip, synacode;
blcksock, synautil, asn1util, synaip, synacode, synacrypt;
const
cSnmpProtocol = '161';
@ -125,6 +128,12 @@ type
AuthMD5,
AuthSHA1);
{:@abstract(Type of SNMPv3 privacy)}
TV3Priv = (
PrivDES,
Priv3DES,
PrivAES);
{:@abstract(Data object with one record of MIB OID and corresponding values.)}
TSNMPMib = class(TObject)
protected
@ -175,19 +184,25 @@ type
FUserName: AnsiString;
FPassword: AnsiString;
FAuthKey: AnsiString;
FPrivMode: TV3Priv;
FPrivPassword: AnsiString;
FPrivKey: AnsiString;
FPrivSalt: AnsiString;
FPrivSaltCounter: integer;
FOldTrapEnterprise: AnsiString;
FOldTrapHost: AnsiString;
FOldTrapGen: Integer;
FOldTrapSpec: Integer;
FOldTrapTimeTicks: Integer;
function Pass2Key(const Value: AnsiString): AnsiString;
function EncryptPDU(const value: AnsiString): AnsiString;
function DecryptPDU(const value: AnsiString): AnsiString;
public
constructor Create;
destructor Destroy; override;
{:Decode SNMP packet in buffer to object properties.}
function DecodeBuf(const Buffer: AnsiString): Boolean;
function DecodeBuf(Buffer: AnsiString): Boolean;
{:Encode obeject properties to SNMP packet.}
function EncodeBuf: AnsiString;
@ -246,8 +261,7 @@ type
{:Maximum message size in bytes for SNMPv3. For sending is default 1472 bytes.}
property MaxSize: Integer read FMaxSize write FMaxSize;
{:Specify if message is authorised or encrypted. Used only in SNMPv3, and
encryption is not yet supported!}
{:Specify if message is authorised or encrypted. Used only in SNMPv3.}
property Flags: TV3Flags read FFlags write FFlags;
{:For SNMPv3.... If is @true, SNMP agent must send reply (at least with some
@ -264,6 +278,9 @@ type
authorization)}
property AuthMode: TV3Auth read FAuthMode write FAuthMode;
{:For SNMPv3. Specify Privacy mode.}
property PrivMode: TV3Priv read FPrivMode write FPrivMode;
{:value used by SNMPv3 authorisation for synchronization with SNMP agent.}
property AuthEngineID: AnsiString read FAuthEngineID write FAuthEngineID;
@ -285,7 +302,10 @@ type
{:For SNMPv3. Computed Athorization key from @link(password).}
property AuthKey: AnsiString read FAuthKey write FAuthKey;
{:For SNMPv3. Encryption key for message encryption. Not yet used!}
{:SNMPv3 privacy password}
property PrivPassword: AnsiString read FPrivPassword write FPrivPassword;
{:For SNMPv3. Computed Privacy key from @link(PrivPassword).}
property PrivKey: AnsiString read FPrivKey write FPrivKey;
{:MIB value to identify the object that sent the TRAPv1.}
@ -417,6 +437,10 @@ begin
inherited Create;
FSNMPMibList := TList.Create;
Clear;
FAuthMode := AuthMD5;
FPassword := '';
FPrivMode := PrivDES;
FPrivPassword := '';
FID := 1;
FMaxSize := 1472;
end;
@ -452,8 +476,66 @@ begin
end;
end;
function TSNMPRec.DecryptPDU(const value: AnsiString): AnsiString;
var
des: TSynaDes;
des3: TSyna3Des;
aes: TSynaAes;
s: string;
begin
FPrivKey := '';
if FFlags <> AuthPriv then
Result := value
else
begin
case FPrivMode of
Priv3DES:
begin
FPrivKey := Pass2Key(FPrivPassword);
FPrivKey := FPrivKey + Pass2Key(FPrivKey);
des3 := TSyna3Des.Create(PadString(FPrivKey, 24, #0));
try
s := PadString(FPrivKey, 32, #0);
delete(s, 1, 24);
des3.SetIV(xorstring(s, FPrivSalt));
s := des3.DecryptCBC(value);
Result := s;
finally
des3.free;
end;
end;
PrivAES:
begin
FPrivKey := Pass2Key(FPrivPassword);
aes := TSynaAes.Create(PadString(FPrivKey, 16, #0));
try
s := CodeLongInt(FAuthEngineBoots) + CodeLongInt(FAuthEngineTime) + FPrivSalt;
aes.SetIV(s);
s := aes.DecryptCFBblock(value);
Result := s;
finally
aes.free;
end;
end;
else //PrivDES as default
begin
FPrivKey := Pass2Key(FPrivPassword);
des := TSynaDes.Create(PadString(FPrivKey, 8, #0));
try
s := PadString(FPrivKey, 16, #0);
delete(s, 1, 8);
des.SetIV(xorstring(s, FPrivSalt));
s := des.DecryptCBC(value);
Result := s;
finally
des.free;
end;
end;
end;
end;
end;
function TSNMPRec.DecodeBuf(const Buffer: AnsiString): Boolean;
function TSNMPRec.DecodeBuf(Buffer: AnsiString): Boolean;
var
Pos: Integer;
EndPos: Integer;
@ -508,14 +590,24 @@ begin
FAuthEngineTimeStamp := GetTick;
FUserName := ASNItem(SPos, s, Svt);
FAuthKey := ASNItem(SPos, s, Svt);
FPrivKey := ASNItem(SPos, s, Svt);
FPrivSalt := ASNItem(SPos, s, Svt);
end;
//scopedPDU
s := ASNItem(Pos, Buffer, Svt);
if Svt = ASN1_OCTSTR then
if FFlags = AuthPriv then
begin
//decrypt!
x := Pos;
s := ASNItem(Pos, Buffer, Svt);
if Svt <> ASN1_OCTSTR then
exit;
s := DecryptPDU(s);
//replace encoded content by decoded version and continue
Buffer := copy(Buffer, 1, x - 1);
Buffer := Buffer + s;
Pos := x;
if length(Buffer) < EndPos then
EndPos := length(buffer);
end;
ASNItem(Pos, Buffer, Svt); //skip sequence mark
FContextEngineID := ASNItem(Pos, Buffer, Svt);
FContextName := ASNItem(Pos, Buffer, Svt);
end
@ -547,11 +639,88 @@ begin
ASNItem(Pos, Buffer, Svt);
Sm := ASNItem(Pos, Buffer, Svt);
Sv := ASNItem(Pos, Buffer, Svt);
Self.MIBAdd(sm, sv, Svt);
if sm <> '' then
Self.MIBAdd(sm, sv, Svt);
end;
Result := True;
end;
function TSNMPRec.EncryptPDU(const value: AnsiString): AnsiString;
var
des: TSynaDes;
des3: TSyna3Des;
aes: TSynaAes;
s: string;
x: integer;
begin
FPrivKey := '';
if FFlags <> AuthPriv then
Result := Value
else
begin
case FPrivMode of
Priv3DES:
begin
FPrivKey := Pass2Key(FPrivPassword);
FPrivKey := FPrivKey + Pass2Key(FPrivKey);
des3 := TSyna3Des.Create(PadString(FPrivKey, 24, #0));
try
s := PadString(FPrivKey, 32, #0);
delete(s, 1, 24);
FPrivSalt := CodeLongInt(FAuthEngineBoots) + CodeLongInt(FPrivSaltCounter);
inc(FPrivSaltCounter);
s := xorstring(s, FPrivSalt);
des3.SetIV(s);
x := length(value) mod 8;
x := 8 - x;
if x = 8 then
x := 0;
s := des3.EncryptCBC(value + Stringofchar(#0, x));
Result := ASNObject(s, ASN1_OCTSTR);
finally
des3.free;
end;
end;
PrivAES:
begin
FPrivKey := Pass2Key(FPrivPassword);
aes := TSynaAes.Create(PadString(FPrivKey, 16, #0));
try
FPrivSalt := CodeLongInt(0) + CodeLongInt(FPrivSaltCounter);
inc(FPrivSaltCounter);
s := CodeLongInt(FAuthEngineBoots) + CodeLongInt(FAuthEngineTime) + FPrivSalt;
aes.SetIV(s);
s := aes.EncryptCFBblock(value);
Result := ASNObject(s, ASN1_OCTSTR);
finally
aes.free;
end;
end;
else //PrivDES as default
begin
FPrivKey := Pass2Key(FPrivPassword);
des := TSynaDes.Create(PadString(FPrivKey, 8, #0));
try
s := PadString(FPrivKey, 16, #0);
delete(s, 1, 8);
FPrivSalt := CodeLongInt(FAuthEngineBoots) + CodeLongInt(FPrivSaltCounter);
inc(FPrivSaltCounter);
s := xorstring(s, FPrivSalt);
des.SetIV(s);
x := length(value) mod 8;
x := 8 - x;
if x = 8 then
x := 0;
s := des.EncryptCBC(value + Stringofchar(#0, x));
Result := ASNObject(s, ASN1_OCTSTR);
finally
des.free;
end;
end;
end;
end;
end;
function TSNMPRec.EncodeBuf: AnsiString;
var
s: AnsiString;
@ -610,8 +779,9 @@ begin
pdu := ASNObject(FContextEngineID, ASN1_OCTSTR)
+ ASNObject(FContextName, ASN1_OCTSTR)
+ pdu;
//maybe encrypt pdu... in future
pdu := ASNObject(pdu, ASN1_SEQ);
//encrypt PDU if Priv mode is enabled
pdu := EncryptPDU(pdu);
//prepare flags
case FFlags of
@ -646,7 +816,7 @@ begin
AuthPriv:
begin
s := authbeg + ASNObject(StringOfChar(#0, 12), ASN1_OCTSTR)
+ ASNObject(FPrivKey, ASN1_OCTSTR);
+ ASNObject(FPrivSalt, ASN1_OCTSTR);
s := ASNObject(s, ASN1_SEQ);
s := head + ASNObject(s, ASN1_OCTSTR);
s := ASNObject(s + pdu, ASN1_SEQ);
@ -672,7 +842,7 @@ begin
end;
auth := authbeg + ASNObject(FAuthKey, ASN1_OCTSTR)
+ ASNObject(FPrivKey, ASN1_OCTSTR);
+ ASNObject(FPrivSalt, ASN1_OCTSTR);
auth := ASNObject(auth, ASN1_SEQ);
head := head + ASNObject(auth, ASN1_OCTSTR);
@ -694,7 +864,6 @@ begin
FVersion := SNMP_V1;
FCommunity := 'public';
FUserName := '';
FPassword := '';
FPDUType := 0;
FErrorStatus := 0;
FErrorIndex := 0;
@ -710,13 +879,14 @@ begin
FFlagReportable := false;
FContextEngineID := '';
FContextName := '';
FAuthMode := AuthMD5;
FAuthEngineID := '';
FAuthEngineBoots := 0;
FAuthEngineTime := 0;
FAuthEngineTimeStamp := 0;
FAuthKey := '';
FPrivKey := '';
FPrivSalt := '';
FPrivSaltCounter := random(maxint);
end;
procedure TSNMPRec.MIBAdd(const MIB, Value: AnsiString; ValueType: Integer);
@ -813,6 +983,10 @@ end;
function TSNMPSend.InternalSendRequest(const QValue, RValue: TSNMPRec): Boolean;
begin
Result := False;
RValue.AuthMode := QValue.AuthMode;
RValue.Password := QValue.Password;
RValue.PrivMode := QValue.PrivMode;
RValue.PrivPassword := QValue.PrivPassword;
FSock.Bind(FIPInterface, cAnyPort);
FSock.Connect(FTargetHost, FTargetPort);
if InternalSendSnmp(QValue) then
@ -832,10 +1006,7 @@ begin
FQuery.AuthEngineTimeStamp := Sync.EngineStamp;
FQuery.AuthEngineID := Sync.EngineID;
end;
FSock.Bind(FIPInterface, cAnyPort);
FSock.Connect(FTargetHost, FTargetPort);
if InternalSendSnmp(FQuery) then
Result := InternalRecvSnmp(FReply);
Result := InternalSendRequest(FQuery, FReply);
end;
function TSNMPSend.SendTrap: Boolean;
@ -892,6 +1063,9 @@ begin
SyncQuery.Password := FQuery.Password;
SyncQuery.FlagReportable := True;
SyncQuery.Flags := FQuery.Flags;
SyncQuery.AuthMode := FQuery.AuthMode;
SyncQuery.PrivMode := FQuery.PrivMode;
SyncQuery.PrivPassword := FQuery.PrivPassword;
SyncQuery.PDUType := PDUGetRequest;
SyncQuery.AuthEngineID := FReply.FAuthEngineID;
if InternalSendRequest(SyncQuery, FReply) then

View File

@ -498,7 +498,7 @@ const
96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22);
@ -564,7 +564,7 @@ const
($2d,$9b,$9b,$b6), ($3c,$1e,$1e,$22), ($15,$87,$87,$92), ($c9,$e9,$e9,$20),
($87,$ce,$ce,$49), ($aa,$55,$55,$ff), ($50,$28,$28,$78), ($a5,$df,$df,$7a),
($03,$8c,$8c,$8f), ($59,$a1,$a1,$f8), ($09,$89,$89,$80), ($1a,$0d,$0d,$17),
($65,$bf,$bf,$da), ($d7,$e6,$e6,$31), ($84,$42,$42,$c6), ($d0,$68,$68,$b8),
($65,$bf,$bf,$da), ($d7,$e6,$e6,$31), ($84,$42,$42,$c6), ($d0,$68,$68,$b8),
($82,$41,$41,$c3), ($29,$99,$99,$b0), ($5a,$2d,$2d,$77), ($1e,$0f,$0f,$11),
($7b,$b0,$b0,$cb), ($a8,$54,$54,$fc), ($6d,$bb,$bb,$d6), ($2c,$16,$16,$3a));
T2: array[0..255,0..3] of byte= (
@ -597,7 +597,7 @@ const
($cf,$8a,$45,$45), ($10,$e9,$f9,$f9), ($06,$04,$02,$02), ($81,$fe,$7f,$7f),
($f0,$a0,$50,$50), ($44,$78,$3c,$3c), ($ba,$25,$9f,$9f), ($e3,$4b,$a8,$a8),
($f3,$a2,$51,$51), ($fe,$5d,$a3,$a3), ($c0,$80,$40,$40), ($8a,$05,$8f,$8f),
($ad,$3f,$92,$92), ($bc,$21,$9d,$9d), ($48,$70,$38,$38), ($04,$f1,$f5,$f5),
($ad,$3f,$92,$92), ($bc,$21,$9d,$9d), ($48,$70,$38,$38), ($04,$f1,$f5,$f5),
($df,$63,$bc,$bc), ($c1,$77,$b6,$b6), ($75,$af,$da,$da), ($63,$42,$21,$21),
($30,$20,$10,$10), ($1a,$e5,$ff,$ff), ($0e,$fd,$f3,$f3), ($6d,$bf,$d2,$d2),
($4c,$81,$cd,$cd), ($14,$18,$0c,$0c), ($35,$26,$13,$13), ($2f,$c3,$ec,$ec),
@ -663,7 +663,7 @@ const
($50,$f0,$a0,$50), ($3c,$44,$78,$3c), ($9f,$ba,$25,$9f), ($a8,$e3,$4b,$a8),
($51,$f3,$a2,$51), ($a3,$fe,$5d,$a3), ($40,$c0,$80,$40), ($8f,$8a,$05,$8f),
($92,$ad,$3f,$92), ($9d,$bc,$21,$9d), ($38,$48,$70,$38), ($f5,$04,$f1,$f5),
($bc,$df,$63,$bc), ($b6,$c1,$77,$b6), ($da,$75,$af,$da), ($21,$63,$42,$21),
($bc,$df,$63,$bc), ($b6,$c1,$77,$b6), ($da,$75,$af,$da), ($21,$63,$42,$21),
($10,$30,$20,$10), ($ff,$1a,$e5,$ff), ($f3,$0e,$fd,$f3), ($d2,$6d,$bf,$d2),
($cd,$4c,$81,$cd), ($0c,$14,$18,$0c), ($13,$35,$26,$13), ($ec,$2f,$c3,$ec),
($5f,$e1,$be,$5f), ($97,$a2,$35,$97), ($44,$cc,$88,$44), ($17,$39,$2e,$17),
@ -795,7 +795,7 @@ const
($80,$c0,$c5,$4f), ($61,$dc,$20,$a2), ($5a,$77,$4b,$69), ($1c,$12,$1a,$16),
($e2,$93,$ba,$0a), ($c0,$a0,$2a,$e5), ($3c,$22,$e0,$43), ($12,$1b,$17,$1d),
($0e,$09,$0d,$0b), ($f2,$8b,$c7,$ad), ($2d,$b6,$a8,$b9), ($14,$1e,$a9,$c8),
($57,$f1,$19,$85), ($af,$75,$07,$4c), ($ee,$99,$dd,$bb), ($a3,$7f,$60,$fd),
($57,$f1,$19,$85), ($af,$75,$07,$4c), ($ee,$99,$dd,$bb), ($a3,$7f,$60,$fd),
($f7,$01,$26,$9f), ($5c,$72,$f5,$bc), ($44,$66,$3b,$c5), ($5b,$fb,$7e,$34),
($8b,$43,$29,$76), ($cb,$23,$c6,$dc), ($b6,$ed,$fc,$68), ($b8,$e4,$f1,$63),
($d7,$31,$dc,$ca), ($42,$63,$85,$10), ($13,$97,$22,$40), ($84,$c6,$11,$20),
@ -861,7 +861,7 @@ const
($0a,$e2,$93,$ba), ($e5,$c0,$a0,$2a), ($43,$3c,$22,$e0), ($1d,$12,$1b,$17),
($0b,$0e,$09,$0d), ($ad,$f2,$8b,$c7), ($b9,$2d,$b6,$a8), ($c8,$14,$1e,$a9),
($85,$57,$f1,$19), ($4c,$af,$75,$07), ($bb,$ee,$99,$dd), ($fd,$a3,$7f,$60),
($9f,$f7,$01,$26), ($bc,$5c,$72,$f5), ($c5,$44,$66,$3b), ($34,$5b,$fb,$7e),
($9f,$f7,$01,$26), ($bc,$5c,$72,$f5), ($c5,$44,$66,$3b), ($34,$5b,$fb,$7e),
($76,$8b,$43,$29), ($dc,$cb,$23,$c6), ($68,$b6,$ed,$fc), ($63,$b8,$e4,$f1),
($ca,$d7,$31,$dc), ($10,$42,$63,$85), ($40,$13,$97,$22), ($20,$84,$c6,$11),
($7d,$85,$4a,$24), ($f8,$d2,$bb,$3d), ($11,$ae,$f9,$32), ($6d,$c7,$29,$a1),
@ -927,7 +927,7 @@ const
($0d,$0b,$0e,$09), ($c7,$ad,$f2,$8b), ($a8,$b9,$2d,$b6), ($a9,$c8,$14,$1e),
($19,$85,$57,$f1), ($07,$4c,$af,$75), ($dd,$bb,$ee,$99), ($60,$fd,$a3,$7f),
($26,$9f,$f7,$01), ($f5,$bc,$5c,$72), ($3b,$c5,$44,$66), ($7e,$34,$5b,$fb),
($29,$76,$8b,$43), ($c6,$dc,$cb,$23), ($fc,$68,$b6,$ed), ($f1,$63,$b8,$e4),
($29,$76,$8b,$43), ($c6,$dc,$cb,$23), ($fc,$68,$b6,$ed), ($f1,$63,$b8,$e4),
($dc,$ca,$d7,$31), ($85,$10,$42,$63), ($22,$40,$13,$97), ($11,$20,$84,$c6),
($24,$7d,$85,$4a), ($3d,$f8,$d2,$bb), ($32,$11,$ae,$f9), ($a1,$6d,$c7,$29),
($2f,$4b,$1d,$9e), ($30,$f3,$dc,$b2), ($52,$ec,$0d,$86), ($e3,$d0,$77,$c1),
@ -1092,7 +1092,7 @@ const
($38,$24,$34,$2c), ($36,$2d,$39,$27), ($24,$36,$2e,$3a), ($2a,$3f,$23,$31),
($70,$48,$68,$58), ($7e,$41,$65,$53), ($6c,$5a,$72,$4e), ($62,$53,$7f,$45),
($48,$6c,$5c,$74), ($46,$65,$51,$7f), ($54,$7e,$46,$62), ($5a,$77,$4b,$69),
($e0,$90,$d0,$b0), ($ee,$99,$dd,$bb), ($fc,$82,$ca,$a6), ($f2,$8b,$c7,$ad),
($e0,$90,$d0,$b0), ($ee,$99,$dd,$bb), ($fc,$82,$ca,$a6), ($f2,$8b,$c7,$ad),
($d8,$b4,$e4,$9c), ($d6,$bd,$e9,$97), ($c4,$a6,$fe,$8a), ($ca,$af,$f3,$81),
($90,$d8,$b8,$e8), ($9e,$d1,$b5,$e3), ($8c,$ca,$a2,$fe), ($82,$c3,$af,$f5),
($a8,$fc,$8c,$c4), ($a6,$f5,$81,$cf), ($b4,$ee,$96,$d2), ($ba,$e7,$9b,$d9),
@ -1125,7 +1125,7 @@ const
($31,$a4,$b2,$af), ($3f,$ad,$bf,$a4), ($2d,$b6,$a8,$b9), ($23,$bf,$a5,$b2),
($09,$80,$86,$83), ($07,$89,$8b,$88), ($15,$92,$9c,$95), ($1b,$9b,$91,$9e),
($a1,$7c,$0a,$47), ($af,$75,$07,$4c), ($bd,$6e,$10,$51), ($b3,$67,$1d,$5a),
($99,$58,$3e,$6b), ($97,$51,$33,$60), ($85,$4a,$24,$7d), ($8b,$43,$29,$76),
($99,$58,$3e,$6b), ($97,$51,$33,$60), ($85,$4a,$24,$7d), ($8b,$43,$29,$76),
($d1,$34,$62,$1f), ($df,$3d,$6f,$14), ($cd,$26,$78,$09), ($c3,$2f,$75,$02),
($e9,$10,$56,$33), ($e7,$19,$5b,$38), ($f5,$02,$4c,$25), ($fb,$0b,$41,$2e),
($9a,$d7,$61,$8c), ($94,$de,$6c,$87), ($86,$c5,$7b,$9a), ($88,$cc,$76,$91),
@ -1158,7 +1158,7 @@ const
($58,$70,$48,$68), ($53,$7e,$41,$65), ($4e,$6c,$5a,$72), ($45,$62,$53,$7f),
($74,$48,$6c,$5c), ($7f,$46,$65,$51), ($62,$54,$7e,$46), ($69,$5a,$77,$4b),
($b0,$e0,$90,$d0), ($bb,$ee,$99,$dd), ($a6,$fc,$82,$ca), ($ad,$f2,$8b,$c7),
($9c,$d8,$b4,$e4), ($97,$d6,$bd,$e9), ($8a,$c4,$a6,$fe), ($81,$ca,$af,$f3),
($9c,$d8,$b4,$e4), ($97,$d6,$bd,$e9), ($8a,$c4,$a6,$fe), ($81,$ca,$af,$f3),
($e8,$90,$d8,$b8), ($e3,$9e,$d1,$b5), ($fe,$8c,$ca,$a2), ($f5,$82,$c3,$af),
($c4,$a8,$fc,$8c), ($cf,$a6,$f5,$81), ($d2,$b4,$ee,$96), ($d9,$ba,$e7,$9b),
($7b,$db,$3b,$bb), ($70,$d5,$32,$b6), ($6d,$c7,$29,$a1), ($66,$c9,$20,$ac),
@ -1191,7 +1191,7 @@ const
($83,$09,$80,$86), ($88,$07,$89,$8b), ($95,$15,$92,$9c), ($9e,$1b,$9b,$91),
($47,$a1,$7c,$0a), ($4c,$af,$75,$07), ($51,$bd,$6e,$10), ($5a,$b3,$67,$1d),
($6b,$99,$58,$3e), ($60,$97,$51,$33), ($7d,$85,$4a,$24), ($76,$8b,$43,$29),
($1f,$d1,$34,$62), ($14,$df,$3d,$6f), ($09,$cd,$26,$78), ($02,$c3,$2f,$75),
($1f,$d1,$34,$62), ($14,$df,$3d,$6f), ($09,$cd,$26,$78), ($02,$c3,$2f,$75),
($33,$e9,$10,$56), ($38,$e7,$19,$5b), ($25,$f5,$02,$4c), ($2e,$fb,$0b,$41),
($8c,$9a,$d7,$61), ($87,$94,$de,$6c), ($9a,$86,$c5,$7b), ($91,$88,$cc,$76),
($a0,$a2,$f3,$55), ($ab,$ac,$fa,$58), ($b6,$be,$e1,$4f), ($bd,$b0,$e8,$42),
@ -1290,7 +1290,7 @@ const
($90,$d0,$b0,$e0), ($99,$dd,$bb,$ee), ($82,$ca,$a6,$fc), ($8b,$c7,$ad,$f2),
($b4,$e4,$9c,$d8), ($bd,$e9,$97,$d6), ($a6,$fe,$8a,$c4), ($af,$f3,$81,$ca),
($d8,$b8,$e8,$90), ($d1,$b5,$e3,$9e), ($ca,$a2,$fe,$8c), ($c3,$af,$f5,$82),
($fc,$8c,$c4,$a8), ($f5,$81,$cf,$a6), ($ee,$96,$d2,$b4), ($e7,$9b,$d9,$ba),
($fc,$8c,$c4,$a8), ($f5,$81,$cf,$a6), ($ee,$96,$d2,$b4), ($e7,$9b,$d9,$ba),
($3b,$bb,$7b,$db), ($32,$b6,$70,$d5), ($29,$a1,$6d,$c7), ($20,$ac,$66,$c9),
($1f,$8f,$57,$e3), ($16,$82,$5c,$ed), ($0d,$95,$41,$ff), ($04,$98,$4a,$f1),
($73,$d3,$23,$ab), ($7a,$de,$28,$a5), ($61,$c9,$35,$b7), ($68,$c4,$3e,$b9),
@ -1356,16 +1356,6 @@ const
type
PDWord = ^LongWord;
function XorString(Indata1, Indata2: AnsiString): AnsiString;
var
i: integer;
begin
Indata2 := PadString(Indata2, length(Indata1), #0);
Result := '';
for i := 1 to length(Indata1) do
Result := Result + AnsiChar(ord(Indata1[i]) xor ord(Indata2[i]));
end;
procedure hperm_op(var a, t: integer; n, m: integer);
begin
t:= ((a shl (16 - n)) xor a) and m;

View File

@ -1,5 +1,5 @@
{==============================================================================|
| Project : Ararat Synapse | 004.014.000 |
| Project : Ararat Synapse | 004.014.001 |
|==============================================================================|
| Content: support procedures and functions |
|==============================================================================|
@ -324,6 +324,9 @@ function GetTempFile(const Dir, prefix: AnsiString): AnsiString;
smaller, string is padded by Pad character.}
function PadString(const Value: AnsiString; len: integer; Pad: AnsiChar): AnsiString;
{:XOR each byte in the strings}
function XorString(Indata1, Indata2: AnsiString): AnsiString;
{:Read header from "Value" stringlist beginning at "Index" position. If header
is Splitted into multiple lines, then this procedure de-split it into one line.}
function NormalizeHeader(Value: TStrings; var Index: Integer): string;
@ -1781,6 +1784,18 @@ end;
{==============================================================================}
function XorString(Indata1, Indata2: AnsiString): AnsiString;
var
i: integer;
begin
Indata2 := PadString(Indata2, length(Indata1), #0);
Result := '';
for i := 1 to length(Indata1) do
Result := Result + AnsiChar(ord(Indata1[i]) xor ord(Indata2[i]));
end;
{==============================================================================}
function NormalizeHeader(Value: TStrings; var Index: Integer): string;
var
s, t: string;