Componentes.Terceros.DevExp.../official/x.48/ExpressPrinting System 4/Sources/dxPSPDFCrypt.pas
2010-01-18 18:33:24 +00:00

331 lines
11 KiB
ObjectPascal

{*******************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressPrinting System COMPONENT SUITE }
{ }
{ Copyright (C) 1998-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSPRINTINGSYSTEM AND }
{ ALL ACCOMPANYING VCL CONTROLS AS PART OF AN }
{ EXECUTABLE PROGRAM ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{*******************************************************************}
unit dxPSPDFCrypt;
interface
uses
Windows, SysUtils, Classes, Math, dxCore;
type
TdxRC4Key = array[0..255] of Byte;
TdxMD5Byte16 = array[0..15] of Byte;
TdxMD5Byte64 = array[0..63] of Byte;
PdxMD5Byte64 = ^TdxMD5Byte64;
TdxMD5Int2 = array[0..1] of Cardinal;
TdxMD5Int4 = array[0..3] of Cardinal;
TdxMD5Int16 = array[0..15] of Cardinal;
PdxMD5Int16 = ^TdxMD5Int16;
TdxMD5Context = record
State: TdxMD5Int4;
Count: TdxMD5Int2;
Buffer: TdxMD5Byte64;
BufferLen: Cardinal;
end;
function dxMD5CalcStr(const S: string): string;
function dxMD5DigestToString(const ADigest: TdxMD5Byte16): string;
procedure dxMD5Calc(AInput: PByteArray; AInputLength: Integer; var ADigest: TdxMD5Byte16);
procedure dxMD5Final(var AContext: TdxMD5Context; var ADigest: TdxMD5Byte16);
procedure dxMD5Init(var AContext: TdxMD5Context);
procedure dxMD5Update(var AContext: TdxMD5Context; AInput: PByteArray; AInputLength: Integer); overload;
procedure dxMD5Update(var AContext: TdxMD5Context; const S: AnsiString); overload;
procedure dxRC4Crypt(var AKey: TdxRC4Key; AInData, AOutData: PByteArray; ADataSize: Integer);
procedure dxRC4Initialize(out AKey: TdxRC4Key; APassword: PByteArray; APasswordLength: Integer);
implementation
const
FFTable: array[0..15] of LongWord = (
$d76aa478, $e8c7b756, $242070db, $c1bdceee,
$f57c0faf, $4787c62a, $a8304613, $fd469501,
$698098d8, $8b44f7af, $ffff5bb1, $895cd7be,
$6b901122, $fd987193, $a679438e, $49b40821
);
GGTable: array[0..15] of LongWord = (
$f61e2562, $c040b340, $265e5a51, $e9b6c7aa,
$d62f105d, $02441453, $d8a1e681, $e7d3fbc8,
$21e1cde6, $c33707d6, $f4d50d87, $455a14ed,
$a9e3e905, $fcefa3f8, $676f02d9, $8d2a4c8a
);
HHTable: array[0..15] of LongWord = (
$fffa3942, $8771f681, $6d9d6122, $fde5380c,
$a4beea44, $4bdecfa9, $f6bb4b60, $bebfbc70,
$289b7ec6, $eaa127fa, $d4ef3085, $04881d05,
$d9d4d039, $e6db99e5, $1fa27cf8, $c4ac5665
);
IITable: array[0..15] of LongWord = (
$f4292244, $432aff97, $ab9423a7, $fc93a039,
$655b59c3, $8f0ccc92, $ffeff47d, $85845dd1,
$6fa87e4f, $fe2ce6e0, $a3014314, $4e0811a1,
$f7537e82, $bd3af235, $2ad7d2bb, $eb86d391
);
function ROL(X, N: LongWord): LongWord;
begin
Result := (X shl N) or (X shr (32 - N));
end;
function FF(A, B, C, D, X, S, AC: LongWord): LongWord;
begin
Result := ROL(A + X + AC + (B and C or not B and D), S) + B;
end;
function GG(A, B, C, D, X, S, AC: LongWord): LongWord;
begin
Result := ROL(A + X + AC + (B and D or C and not D), S) + B;
end;
function HH(A, B, C, D, X, S, AC: LongWord): LongWord;
begin
Result := ROL(A + X + AC + (B xor C xor D), S) + B;
end;
function II(A, B, C, D, X, S, AC: LongWord): LongWord;
begin
Result := ROL(A + X + AC + (C xor (B or not D)), S) + B;
end;
procedure dxMD5Init(var AContext: TdxMD5Context);
begin
ZeroMemory(@AContext, SizeOf(AContext));
AContext.State[0] := $67452301;
AContext.State[1] := $EFCDAB89;
AContext.State[2] := $98BADCFE;
AContext.State[3] := $10325476;
end;
procedure dxMD5Transform(var AAccumulator: TdxMD5Int4; const ABuf: PdxMD5Int16);
function CalcPos(ARow, AOffset: Integer): Integer;
begin
Result := ARow * 4 + AOffset;
if Result < 0 then
Inc(Result, 16);
if Result >= 16 then
Dec(Result, 16);
end;
var
A, B, C, D: LongWord;
I: Integer;
begin
A := AAccumulator[0];
B := AAccumulator[1];
C := AAccumulator[2];
D := AAccumulator[3];
for I := 0 to 3 do
begin
A := FF(A, B, C, D, ABuf^[CalcPos(I, 0)], 7, FFTable[4 * I + 0]);
D := FF(D, A, B, C, ABuf^[CalcPos(I, 1)], 12, FFTable[4 * I + 1]);
C := FF(C, D, A, B, ABuf^[CalcPos(I, 2)], 17, FFTable[4 * I + 2]);
B := FF(B, C, D, A, ABuf^[CalcPos(I, 3)], 22, FFTable[4 * I + 3]);
end;
for I := 0 to 3 do
begin
A := GG(A, B, C, D, ABuf^[CalcPos(I, 1)], 5, GGTable[4 * I + 0]);
D := GG(D, A, B, C, ABuf^[CalcPos(I, 6)], 9, GGTable[4 * I + 1]);
C := GG(C, D, A, B, ABuf^[CalcPos(I, 11)], 14, GGTable[4 * I + 2]);
B := GG(B, C, D, A, ABuf^[CalcPos(I, 0)], 20, GGTable[4 * I + 3]);
end;
for I := 0 to 3 do
begin
A := HH(A, B, C, D, ABuf^[CalcPos(-I, 5)], 4, HHTable[4 * I + 0]);
D := HH(D, A, B, C, ABuf^[CalcPos(-I, 8)], 11, HHTable[4 * I + 1]);
C := HH(C, D, A, B, ABuf^[CalcPos(-I, 11)], 16, HHTable[4 * I + 2]);
B := HH(B, C, D, A, ABuf^[CalcPos(-I, 14)], 23, HHTable[4 * I + 3]);
end;
for I := 0 to 3 do
begin
A := II(A, B, C, D, ABuf^[CalcPos(-I, 0)], 6, IITable[4 * I + 0]);
D := II(D, A, B, C, ABuf^[CalcPos(-I, 7)], 10, IITable[4 * I + 1]);
C := II(C, D, A, B, ABuf^[CalcPos(-I, 14)], 15, IITable[4 * I + 2]);
B := II(B, C, D, A, ABuf^[CalcPos(-I, 5)], 21, IITable[4 * I + 3]);
end;
Inc(AAccumulator[0], A);
Inc(AAccumulator[1], B);
Inc(AAccumulator[2], C);
Inc(AAccumulator[3], D);
end;
procedure dxMD5Update(var AContext: TdxMD5Context; const S: AnsiString);
begin
dxMD5Update(AContext, @S[1], Length(S));
end;
procedure dxMD5Update(var AContext: TdxMD5Context; AInput: PByteArray; AInputLength: Integer);
const
SplitPartSize = 64;
var
AIndex: Integer;
ALeft: Integer;
begin
AIndex := 0;
if Integer(AInputLength shl 3) < 0 then
Inc(AContext.Count[1]);
Inc(AContext.Count[0], AInputLength shl 3);
Inc(AContext.Count[1], AInputLength shr 29);
if AContext.BufferLen > 0 then
begin
ALeft := Min(AInputLength, SplitPartSize - AContext.BufferLen);
Move(AInput^[AIndex], AContext.Buffer[AContext.BufferLen], ALeft);
Inc(AContext.BufferLen, ALeft);
Inc(AIndex, ALeft);
if AContext.BufferLen < SplitPartSize then
Exit;
dxMD5Transform(AContext.State, @AContext.Buffer[0]);
AContext.BufferLen := 0;
end;
while AIndex + SplitPartSize <= AInputLength do
begin
dxMD5Transform(AContext.State, @AInput^[AIndex]);
Inc(AIndex, SplitPartSize);
end;
if AInputLength > AIndex then
begin
AContext.BufferLen := AInputLength - AIndex;
Move(AInput^[AIndex], AContext.Buffer[0], AContext.BufferLen);
end;
end;
procedure dxMD5Final(var AContext: TdxMD5Context; var ADigest: TdxMD5Byte16);
var
AWorkBuf: TdxMD5Byte64;
AWorkLen: Cardinal;
begin
ADigest := TdxMD5Byte16(AContext.State);
Move(AContext.Buffer, AWorkBuf, AContext.BufferLen);
AWorkBuf[AContext.BufferLen] := $80;
AWorkLen := AContext.BufferLen + 1;
if AWorkLen > 56 then
begin
FillChar(AWorkBuf[AWorkLen], 64 - AWorkLen, 0);
dxMD5Transform(TdxMD5Int4(ADigest), @AWorkBuf[0]);
AWorkLen := 0
end;
FillChar(AWorkBuf[AWorkLen], 56 - AWorkLen, 0);
TdxMD5Int16(AWorkBuf)[14] := AContext.Count[0];
TdxMD5Int16(AWorkBuf)[15] := AContext.Count[1];
dxMD5Transform(TdxMD5Int4(ADigest), @AWorkBuf[0]);
FillChar(AContext, SizeOf(AContext), 0);
end;
procedure dxMD5Calc(AInput: PByteArray; AInputLength: Integer; var ADigest: TdxMD5Byte16);
var
AContext: TdxMD5Context;
begin
dxMD5Init(AContext);
dxMD5Update(AContext, AInput, AInputLength);
dxMD5Final(AContext, ADigest);
end;
function dxMD5CalcStr(const S: string): string;
var
AAnsiString: AnsiString;
ADigest: TdxMD5Byte16;
begin
AAnsiString := dxStringToAnsiString(S);
dxMD5Calc(@AAnsiString[1], Length(AAnsiString), ADigest);
Result := dxMD5DigestToString(ADigest);
end;
function dxMD5DigestToString(const ADigest: TdxMD5Byte16): string;
var
I: Integer;
begin
Result := '';
for I := 0 to High(ADigest) do
Result := Result + IntToHex(ADigest[I], 2);
end;
procedure dxRC4Initialize(out AKey: TdxRC4Key; APassword: PByteArray; APasswordLength: Integer);
var
ATempKey: TdxRC4Key;
I, J, K: Integer;
begin
for I := 0 to 255 do
begin
ATempKey[I] := APassword^[I mod APasswordLength];
AKey[I] := I;
end;
J := 0;
for I := 0 to 255 do
begin
J := (J + AKey[I] + ATempKey[I]) and $FF;
K := AKey[I];
AKey[I] := AKey[J];
AKey[j] := K;
end;
end;
procedure dxRC4Crypt(var AKey: TdxRC4Key; AInData, AOutData: PByteArray; ADataSize: Integer);
var
T, K, I, J: Integer;
begin
I := 0;
J := 0;
for K := 0 to ADataSize - 1 do
begin
I := Byte(I + 1);
J := Byte(J + AKey[I]);
T := AKey[I];
AKey[I] := AKey[J];
AKey[J] := T;
T := Byte(AKey[I] + AKey[J]);
AOutData^[K] := AInData^[K] xor AKey[T];
end;
end;
end.