You've already forked lazarus-dcpcrypt
mirror of
https://git.code.sf.net/p/lazarus-ccr/dcpcrypt
synced 2025-11-23 21:44:41 +02:00
* Also implemented a local dcpFillChar() method which uses a 'out' parameter causing less compiler hints.
156 lines
5.4 KiB
ObjectPascal
156 lines
5.4 KiB
ObjectPascal
{******************************************************************************}
|
|
{* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
|
|
{******************************************************************************}
|
|
{* A binary compatible implementation of Tea **********************************}
|
|
{******************************************************************************}
|
|
{* Copyright (c) 1999-2002 David Barton *}
|
|
{* Permission is hereby granted, free of charge, to any person obtaining a *}
|
|
{* copy of this software and associated documentation files (the "Software"), *}
|
|
{* to deal in the Software without restriction, including without limitation *}
|
|
{* the rights to use, copy, modify, merge, publish, distribute, sublicense, *}
|
|
{* and/or sell copies of the Software, and to permit persons to whom the *}
|
|
{* Software is furnished to do so, subject to the following conditions: *}
|
|
{* *}
|
|
{* The above copyright notice and this permission notice shall be included in *}
|
|
{* all copies or substantial portions of the Software. *}
|
|
{* *}
|
|
{* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *}
|
|
{* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *}
|
|
{* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *}
|
|
{* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *}
|
|
{* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *}
|
|
{* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *}
|
|
{* DEALINGS IN THE SOFTWARE. *}
|
|
{******************************************************************************}
|
|
unit DCPtea;
|
|
|
|
{$MODE Delphi}
|
|
|
|
interface
|
|
uses
|
|
Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
|
|
|
|
type
|
|
TDCP_tea= class(TDCP_blockcipher64)
|
|
protected
|
|
KeyData: array[0..3] of dword;
|
|
procedure InitKey(const Key; Size: longword); override;
|
|
public
|
|
class function GetID: integer; override;
|
|
class function GetAlgorithm: string; override;
|
|
class function GetMaxKeySize: integer; override;
|
|
class function SelfTest: boolean; override;
|
|
procedure Burn; override;
|
|
procedure EncryptECB(const InData; var OutData); override;
|
|
procedure DecryptECB(const InData; var OutData); override;
|
|
end;
|
|
|
|
|
|
{******************************************************************************}
|
|
{******************************************************************************}
|
|
implementation
|
|
{$R-}{$Q-}
|
|
|
|
const
|
|
Delta: DWord = $9e3779b9;
|
|
Rounds= 32;
|
|
|
|
function SwapDword(a: dword): dword;
|
|
begin
|
|
Result:= ((a and $FF) shl 24) or ((a and $FF00) shl 8) or ((a and $FF0000) shr 8) or ((a and $FF000000) shr 24);
|
|
end;
|
|
|
|
class function TDCP_tea.GetID: integer;
|
|
begin
|
|
Result:= DCP_tea;
|
|
end;
|
|
|
|
class function TDCP_tea.GetAlgorithm: string;
|
|
begin
|
|
Result:= 'Tea';
|
|
end;
|
|
|
|
class function TDCP_tea.GetMaxKeySize: integer;
|
|
begin
|
|
Result:= 128;
|
|
end;
|
|
|
|
class function TDCP_tea.SelfTest: boolean;
|
|
const
|
|
Key: array[0..3] of dword= ($12345678,$9ABCDEF0,$0FEDCBA9,$87654321);
|
|
PT: array[0..1] of dword= ($12345678,$9ABCDEF0);
|
|
var
|
|
Data: array[0..1] of dword;
|
|
Cipher: TDCP_tea;
|
|
begin
|
|
dcpFillChar(Data, SizeOf(Data), 0);
|
|
Cipher:= TDCP_tea.Create(nil);
|
|
Cipher.Init(Key,Sizeof(Key)*8,nil);
|
|
Cipher.EncryptECB(PT,Data);
|
|
Result:= not CompareMem(@Data,@PT,Sizeof(PT));
|
|
Cipher.DecryptECB(Data,Data);
|
|
Result:= Result and CompareMem(@Data,@PT,Sizeof(PT));
|
|
Cipher.Burn;
|
|
Cipher.Free;
|
|
end;
|
|
|
|
procedure TDCP_tea.InitKey(const Key; Size: longword);
|
|
begin
|
|
FillChar(KeyData,Sizeof(KeyData),0);
|
|
Move(Key,KeyData,Size div 8);
|
|
KeyData[0]:= SwapDWord(KeyData[0]); KeyData[1]:= SwapDWord(KeyData[1]);
|
|
KeyData[2]:= SwapDWord(KeyData[2]); KeyData[3]:= SwapDWord(KeyData[3]);
|
|
end;
|
|
|
|
procedure TDCP_tea.Burn;
|
|
begin
|
|
FillChar(KeyData,Sizeof(KeyData),0);
|
|
inherited Burn;
|
|
end;
|
|
|
|
procedure TDCP_tea.EncryptECB(const InData; var OutData);
|
|
var
|
|
a, b, c, d, x, y, n, sum: dword;
|
|
begin
|
|
if not fInitialized then
|
|
raise EDCP_blockcipher.Create('Cipher not initialized');
|
|
|
|
x:= SwapDWord(pdword(@InData)^);
|
|
y:= SwapDWord(pdword(pointer(@InData)+4)^);
|
|
sum:= 0; a:= KeyData[0]; b:= KeyData[1]; c:= KeyData[2]; d:= KeyData[3];
|
|
for n:= 1 to Rounds do
|
|
begin
|
|
Inc(sum,Delta);
|
|
Inc(x,(y shl 4) + (a xor y) + (sum xor (y shr 5)) + b);
|
|
Inc(y,(x shl 4) + (c xor x) + (sum xor (x shr 5)) + d);
|
|
end;
|
|
pdword(@OutData)^:= SwapDWord(x);
|
|
pdword(pointer(@OutData)+4)^:= SwapDWord(y);
|
|
end;
|
|
|
|
procedure TDCP_tea.DecryptECB(const InData; var OutData);
|
|
var
|
|
a, b, c, d, x, y, n, sum: dword;
|
|
begin
|
|
if not fInitialized then
|
|
raise EDCP_blockcipher.Create('Cipher not initialized');
|
|
|
|
x:= SwapDWord(pdword(@InData)^);
|
|
y:= SwapDWord(pdword(pointer(@InData)+4)^);
|
|
sum:= Delta shl 5;
|
|
a:= KeyData[0];
|
|
b:= KeyData[1];
|
|
c:= KeyData[2];
|
|
d:= KeyData[3];
|
|
for n:= 1 to Rounds do
|
|
begin
|
|
Dec(y,(x shl 4) + (c xor x) + (sum xor (x shr 5)) + d);
|
|
Dec(x,(y shl 4) + (a xor y) + (sum xor (y shr 5)) + b);
|
|
Dec(sum,Delta);
|
|
end;
|
|
pdword(@OutData)^:= SwapDWord(x);
|
|
pdword(pointer(@OutData)+4)^:= SwapDWord(y);
|
|
end;
|
|
|
|
end.
|