You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RnQ/for.RnQ/RnQCrypt.pas

330 lines
6.7 KiB
Plaintext

unit RnQCrypt;
{$I ForRnQConfig.inc}
{$I NoRTTI.inc}
interface
uses
mormot.core.base;
// crypting
function passCrypt(const s: RawByteString): RawByteString;
function passDeCrypt(const s: RawByteString): RawByteString;
function decritted(const s: RawByteString; key: Integer): RawByteString;
function critted(const s: RawByteString; key: Integer): RawByteString;
procedure critt(var s: RawByteString; key: Integer);
procedure decritt(var s: RawByteString; key: Integer);
function calculate_KEY1(const pwd: AnsiString): Integer;
function MD5Pass(const s: RawByteString): RawByteString;
// function qip_msg_decr(s1: RawByteString; s2: AnsiString; n: integer): AnsiString;
// function qip_msg_crypt(s1, s2: AnsiString; n: integer): RawByteString;
function qip_msg_crypt(const s: AnsiString; p: Integer): RawByteString;
function qip_msg_decr(const s1: RawByteString; p: integer): AnsiString;
// function qip_msg_crypt(s1, s2: AnsiString; n: integer): RawByteString;
function qip_str2pass(const s: RawByteString): Integer;
function DigestToString(digest: THash256): RawByteString;
function HashString(const key, str: RawByteString): RawByteString;
implementation
uses
mormot.crypt.core,
{$IFDEF UNICODE}
System.AnsiStrings,
{$ENDIF UNICODE}
Base64, RDUtils;
function passCrypt(const s: RawByteString): RawByteString;
var
i:integer;
begin
result:='';
randSeed:=55555;
i:=length(s);
while i > 0 do
begin
inc(randSeed, ord(s[i]));
dec(i);
end;
i:=length(s);
while i > 0 do
begin
result:=result+ AnsiChar(40+ byte(s[i]) and 15)+ AnsiChar(40+byte(s[i]) shr 4)+ AnsiChar(35+random(35));
while random(3) <> 0 do
result:=result+AnsiChar(70+random(250-70));
dec(i);
end;
end; // passCrypt
function passDecrypt(const s: RawByteString): RawByteString;
var
i:integer;
begin
result:='';
i:=length(s);
while i > 0 do
begin
if s[i] < #70 then
begin
result:=result+AnsiChar((byte(s[i-1])-40) shl 4+ byte(s[i-2])-40);
dec(i,2);
end;
dec(i);
end;
end; // passDecrypt
function decritted(const s:RawByteString; key:integer): RawByteString;
begin
result:=dupString(s);
decritt(result, key);
end;
function critted(const s:RawByteString; key:integer): RawByteString;
begin
result:=dupString(s);
critt(result, key);
end;
{$IFDEF CPUX64}
procedure critt(var s:RawByteString; key:integer);
var
i : Cardinal;
c, d : Byte;
a, b : Byte;
p : PAnsiChar;
begin
if Length(s)=0 then
Exit;
c := Byte(key);
d := Byte(key shr 20);
p := @s[1];
a := $B8;// 10111000b;
for i := 1 to Length(s) do
begin
b := Byte(s[i]) + c;
b := b xor d;
b := (b shr 3) or (b shl 5);
b := b xor a;
p^ := AnsiChar( b );
inc(PAnsiChar(p));
// s[i] := AnsiChar(b);
a := (a shr 3) or (a shl 5);
end;
end;
procedure decritt(var s:RawByteString; key:integer);
var
i : Cardinal;
c, d : Byte;
a, b : Byte;
p : PAnsiChar;
begin
if Length(s)=0 then
Exit;
c := Byte(key);
d := Byte(key shr 20);
p := @s[1];
a := $B8;// 10111000b;
for i := 1 to Length(s) do
begin
b := Byte(s[i]) xor a;
b := (b shl 3) or (b shr 5);
b := b xor d;
b := b - c;
p^ := AnsiChar( b );
inc(PAnsiChar(p));
// s[i] := AnsiChar(b);
a := (a shr 3) or (a shl 5);
end;
end;
{$ELSE ~CPUX64}
{$WARN UNSAFE_CODE OFF}
procedure critt(var s:RawByteString; key:integer);
asm
mov ecx, key
mov dl, cl
shr ecx, 20
mov dh, cl
mov esi, s
mov esi, [esi]
or esi, esi // nil string
jz @OUT
mov ecx, [esi-4] // length
or ecx, ecx
jz @OUT
mov ah, 10111000b
@IN:
mov al, [esi]
add al, dl
xor al, dh
ror al, 3
xor al, ah
mov [esi], al
inc esi
ror ah, 3
dec ecx
jnz @IN
@OUT:
end; // critt
procedure decritt(var s:RawByteString; key:integer);
asm
PUSH ESI // Recommended by <20><>
mov ecx, key
mov dl, cl
shr ecx, 20
mov dh, cl
mov esi, s
mov esi, [esi]
or esi, esi // nil string
jz @OUT
mov ah, 10111000b
mov ecx, [esi-4]
or ecx, ecx
jz @OUT
@IN:
mov al, [esi]
xor al, ah
rol al, 3
xor al, dh
sub al, dl
mov [esi], al
inc esi
ror ah, 3
dec ecx
jnz @IN
@OUT:
POP ESI // Recommended by <20><>
end; // decritt
{$WARN UNSAFE_CODE ON}
{$ENDIF CPUX64}
function calculate_KEY1(const pwd: AnsiString):integer;
var
i,L:integer;
p:^integer;
begin
L:=length(pwd);
result:=L shl 16;
p:=NIL; // shut up compiler warning
if pwd>'' then
p:=@pwd[1];
i:=0;
while i+4 < L do
begin
inc(result, p^);
inc(p);
inc(i,4);
end;
while i < L do
begin
inc(result, ord(pwd[i]));
inc(i);
end;
end; // calculate_KEY1
function MD5Pass(const s: RawBytestring): RawByteString;
var
MD5Digest: TMD5Digest;
MD5: TMD5;
begin
md5.Init;
if Length(s)>0 then
md5.Update(s[1], length(s));
md5.Final(MD5Digest);
SetLength(Result, length(MD5Digest));
StrPLCopy(PAnsiChar(result), PAnsiChar(@MD5Digest), length(MD5Digest))
end;
function qip_msg_crypt(const s: AnsiString; p: Integer): RawByteString;
const
n0 = $1B5F;
var
s5: RawByteString;
n, l, i: integer;
begin
Result := s;
if p=0 then
exit;
Result := '';
s5 := '';
n := n0;
l := Length(s);
if l>0 then
for I := 1 to l do
begin
s5 := s5+ AnsiChar(Byte(s[i]) xor byte(n shr 8));
n:=(Byte(s5[i])+n)*$A8C3+p;
end;
// s5:=_005D6FF8(Result);
Result:= Base64EncodeString(s5);
end;
function qip_str2pass(const s: RawByteString): Integer;
var
l, i: Integer;
begin
Result := 0;
l := Length(s);
if l > 0 then
begin
Result := $3E9;
for I := 1 to l do
Result := Result+ Byte(s[i]);
end;
end;
function qip_msg_decr(const s1: RawByteString; p: integer): AnsiString;
const
n0 = $1B5F;
var
s4: RawByteString;
// a,
n, l: integer;
I: Integer;
begin
if p=0 then
begin
Result := s1;
exit;
end;
Result := '';
n := n0;
// a:=0;
s4 := Base64DecodeString(s1);
l := Length(s4);
if l>0 then
for I := 1 to l do
begin
Result := Result+AnsiChar(Byte(s4[i]) xor byte(n shr 8));
n := (Byte(s4[i])+n)*$A8C3+p;
end;
end;
function DigestToString(digest: TSHA256Digest): RawByteString;
begin
SetString(Result, PAnsiChar(@digest[0]), Length(digest));
end;
function HashString(const key, str: RawByteString): RawByteString;
var
digest: TSHA256Digest;
begin
HmacSha256(key, str, digest);
Result := Base64EncodeString(DigestToString(digest));
end;
end.