home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 December / Chip_2002-12_cd1.bin / ctenari / Hytha / MultiHSH.exe / SR.RAR / SR / DCPCrypt / DCPcrypt2.pas < prev    next >
Pascal/Delphi Source File  |  2002-07-12  |  17KB  |  455 lines

  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* Main component definitions *************************************************}
  5. {******************************************************************************}
  6. {* Copyright (c) 1999-2002 David Barton                                       *}
  7. {* Permission is hereby granted, free of charge, to any person obtaining a    *}
  8. {* copy of this software and associated documentation files (the "Software"), *}
  9. {* to deal in the Software without restriction, including without limitation  *}
  10. {* the rights to use, copy, modify, merge, publish, distribute, sublicense,   *}
  11. {* and/or sell copies of the Software, and to permit persons to whom the      *}
  12. {* Software is furnished to do so, subject to the following conditions:       *}
  13. {*                                                                            *}
  14. {* The above copyright notice and this permission notice shall be included in *}
  15. {* all copies or substantial portions of the Software.                        *}
  16. {*                                                                            *}
  17. {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *}
  18. {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *}
  19. {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *}
  20. {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *}
  21. {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    *}
  22. {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        *}
  23. {* DEALINGS IN THE SOFTWARE.                                                  *}
  24. {******************************************************************************}
  25. unit DCPcrypt2;
  26.  
  27. interface
  28. uses
  29.   Classes, Sysutils, DCPconst, DCPbase64;
  30.  
  31. //{$DEFINE DCP1COMPAT}  { DCPcrypt v1.31 compatiblity mode - see documentation }
  32.  
  33. {******************************************************************************}
  34.     { A few predefined types to help out }
  35.  
  36. type
  37.   Pbyte= ^byte;
  38.   Pword= ^word;
  39.   Pdword= ^dword;
  40.   Pint64= ^int64;
  41.   dword= longword;
  42.   Pwordarray= ^Twordarray;
  43.   Twordarray= array[0..19383] of word;
  44.   Pdwordarray= ^Tdwordarray;
  45.   Tdwordarray= array[0..8191] of dword;
  46.  
  47.  
  48. {******************************************************************************}
  49.     { The base class from which all hash algorithms are to be derived  }
  50.  
  51. type
  52.   EDCP_hash= class(Exception);
  53.   TDCP_hash= class(TComponent)
  54.   protected
  55.     fInitialized: boolean;  { Whether or not the algorithm has been initialized }
  56.  
  57.     procedure DeadInt(Value: integer);   { Knudge to display vars in the object inspector   }
  58.     procedure DeadStr(Value: string);    { Knudge to display vars in the object inspector   }
  59.  
  60.   public
  61.     property Initialized: boolean
  62.       read fInitialized;
  63.  
  64.     class function GetId: integer; virtual; abstract;
  65.       { Get the algorithm id }
  66.     class function GetAlgorithm: string; virtual; abstract;
  67.       { Get the algorithm name }
  68.     class function GetHashSize: integer; virtual; abstract;
  69.       { Get the size of the digest produced - in bits }
  70.     class function SelfTest: boolean; virtual; abstract;
  71.       { Tests the implementation with several test vectors }
  72.  
  73.     procedure Init; virtual; abstract;
  74.       { Initialize the hash algorithm }
  75.     procedure Final(var Digest); virtual; abstract;
  76.       { Create the final digest and clear the stored information.
  77.         The size of the Digest var must be at least equal to the hash size }
  78.     procedure Burn; virtual; abstract;
  79.       { Clear any stored information with out creating the final digest }
  80.  
  81.     procedure Update(const Buffer; Size: longword); virtual; abstract;
  82.       { Update the hash buffer with Size bytes of data from Buffer }
  83.     procedure UpdateStream(Stream: TStream; Size: longword);
  84.       { Update the hash buffer with Size bytes of data from the stream }
  85.     procedure UpdateStr(const Str: string);
  86.       { Update the hash buffer with the string }
  87.  
  88.     destructor Destroy; override;
  89.  
  90.   published
  91.     property Id: integer
  92.       read GetId write DeadInt;
  93.     property Algorithm: string
  94.       read GetAlgorithm write DeadStr;
  95.     property HashSize: integer
  96.       read GetHashSize write DeadInt;
  97.   end;
  98.   TDCP_hashclass= class of TDCP_hash;
  99.  
  100.  
  101. {******************************************************************************}
  102.     { The base class from which all encryption components will be derived. }
  103.     { Stream ciphers will be derived directly from this class where as     }
  104.     { Block ciphers will have a further foundation class TDCP_blockcipher. }
  105.  
  106. type
  107.   EDCP_cipher= class(Exception);
  108.   TDCP_cipher= class(TComponent)
  109.   protected
  110.     fInitialized: boolean;  { Whether or not the key setup has been done yet }
  111.  
  112.     procedure DeadInt(Value: integer);   { Knudge to display vars in the object inspector   }
  113.     procedure DeadStr(Value: string);    { Knudge to display vars in the object inspector   }
  114.  
  115.   public
  116.     property Initialized: boolean
  117.       read fInitialized;
  118.  
  119.     class function GetId: integer; virtual; abstract;
  120.       { Get the algorithm id }
  121.     class function GetAlgorithm: string; virtual; abstract;
  122.       { Get the algorithm name }
  123.     class function GetMaxKeySize: integer; virtual; abstract;
  124.       { Get the maximum key size (in bits) }
  125.     class function SelfTest: boolean; virtual; abstract;
  126.       { Tests the implementation with several test vectors }
  127.  
  128.     procedure Init(const Key; Size: longword; InitVector: pointer); virtual;
  129.       { Do key setup based on the data in Key, size is in bits }
  130.     procedure InitStr(const Key: string; HashType: TDCP_hashclass);
  131.       { Do key setup based on a hash of the key string }
  132.     procedure Burn; virtual;
  133.       { Clear all stored key information }
  134.     procedure Reset; virtual; abstract;
  135.       { Reset any stored chaining information }
  136.     procedure Encrypt(const Indata; var Outdata; Size: longword); virtual; abstract;
  137.       { Encrypt size bytes of data and place in Outdata }
  138.     procedure Decrypt(const Indata; var Outdata; Size: longword); virtual; abstract;
  139.       { Decrypt size bytes of data and place in Outdata }
  140.     function EncryptStream(InStream, OutStream: TStream; Size: longword): longword;
  141.       { Encrypt size bytes of data from InStream and place in OutStream }
  142.     function DecryptStream(InStream, OutStream: TStream; Size: longword): longword;
  143.       { Decrypt size bytes of data from InStream and place in OutStream }
  144.     function EncryptString(const Str: string): string; virtual;
  145.       { Encrypt a string and return Base64 encoded }
  146.     function DecryptString(const Str: string): string; virtual;
  147.       { Decrypt a Base64 encoded string }
  148.  
  149.     constructor Create(AOwner: TComponent); override;
  150.     destructor Destroy; override;
  151.  
  152.   published
  153.     property Id: integer
  154.       read GetId write DeadInt;
  155.     property Algorithm: string
  156.       read GetAlgorithm write DeadStr;
  157.     property MaxKeySize: integer
  158.       read GetMaxKeySize write DeadInt;
  159.   end;
  160.   TDCP_cipherclass= class of TDCP_cipher;
  161.  
  162.  
  163. {******************************************************************************}
  164.     { The base class from which all block ciphers are to be derived, this  }
  165.     { extra class takes care of the different block encryption modes.      }
  166.  
  167. type
  168.   TDCP_ciphermode= (cmCBC, cmCFB8bit, cmCFBblock, cmOFB, cmCTR); // cmCFB8bit is equal to DCPcrypt v1.xx's CFB mode
  169.   EDCP_blockcipher= class(EDCP_cipher);
  170.   TDCP_blockcipher= class(TDCP_cipher)
  171.   protected
  172.     fCipherMode: TDCP_ciphermode;  { The cipher mode the encrypt method uses  }
  173.  
  174.     procedure InitKey(const Key; Size: longword); virtual; abstract;
  175.  
  176.   public
  177.     class function GetBlockSize: integer; virtual; abstract;
  178.       { Get the block size of the cipher (in bits) }
  179.  
  180.     procedure SetIV(const Value); virtual; abstract;
  181.       { Sets the IV to Value and performs a reset }
  182.     procedure GetIV(var Value); virtual; abstract;
  183.       { Returns the current chaining information, not the actual IV }
  184.  
  185.     procedure Encrypt(const Indata; var Outdata; Size: longword); override;
  186.       { Encrypt size bytes of data and place in Outdata using CipherMode }
  187.     procedure Decrypt(const Indata; var Outdata; Size: longword); override;
  188.       { Decrypt size bytes of data and place in Outdata using CipherMode }
  189.     function EncryptString(const Str: string): string; override;
  190.       { Encrypt a string and return Base64 encoded }
  191.     function DecryptString(const Str: string): string; override;
  192.       { Decrypt a Base64 encoded string }
  193.     procedure EncryptECB(const Indata; var Outdata); virtual; abstract;
  194.       { Encrypt a block of data using the ECB method of encryption }
  195.     procedure DecryptECB(const Indata; var Outdata); virtual; abstract;
  196.       { Decrypt a block of data using the ECB method of decryption }
  197.     procedure EncryptCBC(const Indata; var Outdata; Size: longword); virtual; abstract;
  198.       { Encrypt size bytes of data using the CBC method of encryption }
  199.     procedure DecryptCBC(const Indata; var Outdata; Size: longword); virtual; abstract;
  200.       { Decrypt size bytes of data using the CBC method of decryption }
  201.     procedure EncryptCFB8bit(const Indata; var Outdata; Size: longword); virtual; abstract;
  202.       { Encrypt size bytes of data using the CFB (8 bit) method of encryption }
  203.     procedure DecryptCFB8bit(const Indata; var Outdata; Size: longword); virtual; abstract;
  204.       { Decrypt size bytes of data using the CFB (8 bit) method of decryption }
  205.     procedure EncryptCFBblock(const Indata; var Outdata; Size: longword); virtual; abstract;
  206.       { Encrypt size bytes of data using the CFB (block) method of encryption }
  207.     procedure DecryptCFBblock(const Indata; var Outdata; Size: longword); virtual; abstract;
  208.       { Decrypt size bytes of data using the CFB (block) method of decryption }
  209.     procedure EncryptOFB(const Indata; var Outdata; Size: longword); virtual; abstract;
  210.       { Encrypt size bytes of data using the OFB method of encryption }
  211.     procedure DecryptOFB(const Indata; var Outdata; Size: longword); virtual; abstract;
  212.       { Decrypt size bytes of data using the OFB method of decryption }
  213.     procedure EncryptCTR(const Indata; var Outdata; Size: longword); virtual; abstract;
  214.       { Encrypt size bytes of data using the CTR method of encryption }
  215.     procedure DecryptCTR(const Indata; var Outdata; Size: longword); virtual; abstract;
  216.       { Decrypt size bytes of data using the CTR method of decryption }
  217.  
  218.     constructor Create(AOwner: TComponent); override;
  219.  
  220.   published
  221.     property BlockSize: integer
  222.       read GetBlockSize write DeadInt;
  223.     property CipherMode: TDCP_ciphermode
  224.       read fCipherMode write fCipherMode default cmCBC;
  225.   end;
  226.   TDCP_blockcipherclass= class of TDCP_blockcipher;
  227.  
  228.  
  229. {******************************************************************************}
  230.     { Helper functions }
  231.  
  232. procedure XorBlock(var InData1, InData2; Size: longword);
  233.  
  234.  
  235. implementation
  236. {$Q-}{$R-}
  237.  
  238.  
  239. {** TDCP_hash *****************************************************************}
  240.  
  241. procedure TDCP_hash.DeadInt(Value: integer);
  242. begin
  243. end;
  244.  
  245. procedure TDCP_hash.DeadStr(Value: string);
  246. begin
  247. end;
  248.  
  249. procedure TDCP_hash.UpdateStream(Stream: TStream; Size: longword);
  250. var
  251.   Buffer: array[0..8191] of byte;
  252.   i, read: integer;
  253. begin
  254.   for i:= 1 to (Size div Sizeof(Buffer)) do
  255.   begin
  256.     read:= Stream.Read(Buffer,Sizeof(Buffer));
  257.     Update(Buffer,read);
  258.   end;
  259.   if (Size mod Sizeof(Buffer))<> 0 then
  260.   begin
  261.     read:= Stream.Read(Buffer,Size mod Sizeof(Buffer));
  262.     Update(Buffer,read);
  263.   end;
  264. end;
  265.  
  266. procedure TDCP_hash.UpdateStr(const Str: string);
  267. begin
  268.   Update(Str[1],Length(Str));
  269. end;
  270.  
  271. destructor TDCP_hash.Destroy;
  272. begin
  273.   if fInitialized then
  274.     Burn;
  275.   inherited Destroy;
  276. end;
  277.  
  278.  
  279. {** TDCP_cipher ***************************************************************}
  280.  
  281. procedure TDCP_cipher.DeadInt(Value: integer);
  282. begin
  283. end;
  284.  
  285. procedure TDCP_cipher.DeadStr(Value: string);
  286. begin
  287. end;
  288.  
  289. procedure TDCP_cipher.Init(const Key; Size: longword; InitVector: pointer);
  290. begin
  291.   if fInitialized then
  292.     Burn;
  293.   if (Size <= 0) or ((Size and 3)<> 0) or (Size> longword(GetMaxKeySize)) then
  294.     raise EDCP_cipher.Create('Invalid key size')
  295.   else
  296.     fInitialized:= true;
  297. end;
  298.  
  299. procedure TDCP_cipher.InitStr(const Key: string; HashType: TDCP_hashclass);
  300. var
  301.   Hash: TDCP_hash;
  302.   Digest: pointer;
  303. begin
  304.   if fInitialized then
  305.     Burn;
  306.   try
  307.     GetMem(Digest,HashType.GetHashSize div 8);
  308.     Hash:= HashType.Create(Self);
  309.     Hash.Init;
  310.     Hash.UpdateStr(Key);
  311.     Hash.Final(Digest^);
  312.     Hash.Free;
  313.     if MaxKeySize< HashType.GetHashSize then
  314.       Init(Digest^,MaxKeySize,nil)
  315.     else
  316.       Init(Digest^,HashType.GetHashSize,nil);
  317.     FillChar(Digest^,HashType.GetHashSize div 8,$FF);
  318.     FreeMem(Digest);
  319.   except
  320.     raise EDCP_cipher.Create('Unable to allocate sufficient memory for hash digest');
  321.   end;
  322. end;
  323.  
  324. procedure TDCP_cipher.Burn;
  325. begin
  326.   fInitialized:= false;
  327. end;
  328.  
  329. function TDCP_cipher.EncryptStream(InStream, OutStream: TStream; Size: longword): longword;
  330. var
  331.   Buffer: array[0..8191] of byte;
  332.   i, Read: longword;
  333. begin
  334.   Result:= 0;
  335.   for i:= 1 to (Size div Sizeof(Buffer)) do
  336.   begin
  337.     Read:= InStream.Read(Buffer,Sizeof(Buffer));
  338.     Inc(Result,Read);
  339.     Encrypt(Buffer,Buffer,Read);
  340.     OutStream.Write(Buffer,Read);
  341.   end;
  342.   if (Size mod Sizeof(Buffer))<> 0 then
  343.   begin
  344.     Read:= InStream.Read(Buffer,Size mod Sizeof(Buffer));
  345.     Inc(Result,Read);
  346.     Encrypt(Buffer,Buffer,Read);
  347.     OutStream.Write(Buffer,Read);
  348.   end;
  349. end;
  350.  
  351. function TDCP_cipher.DecryptStream(InStream, OutStream: TStream; Size: longword): longword;
  352. var
  353.   Buffer: array[0..8191] of byte;
  354.   i, Read: longword;
  355. begin
  356.   Result:= 0;
  357.   for i:= 1 to (Size div Sizeof(Buffer)) do
  358.   begin
  359.     Read:= InStream.Read(Buffer,Sizeof(Buffer));
  360.     Inc(Result,Read);
  361.     Decrypt(Buffer,Buffer,Read);
  362.     OutStream.Write(Buffer,Read);
  363.   end;
  364.   if (Size mod Sizeof(Buffer))<> 0 then
  365.   begin
  366.     Read:= InStream.Read(Buffer,Size mod Sizeof(Buffer));
  367.     Inc(Result,Read);
  368.     Decrypt(Buffer,Buffer,Read);
  369.     OutStream.Write(Buffer,Read);
  370.   end;
  371. end;
  372.  
  373. function TDCP_cipher.EncryptString(const Str: string): string;
  374. begin
  375.   SetLength(Result,Length(Str));
  376.   Encrypt(Str[1],Result[1],Length(Str));
  377.   Result:= Base64EncodeStr(Result);
  378. end;
  379.  
  380. function TDCP_cipher.DecryptString(const Str: string): string;
  381. begin
  382.   Result:= Base64DecodeStr(Str);
  383.   Decrypt(Result[1],Result[1],Length(Result));
  384. end;
  385.  
  386. constructor TDCP_cipher.Create(AOwner: TComponent);
  387. begin
  388.   inherited Create(AOwner);
  389.   Burn;
  390. end;
  391.  
  392. destructor TDCP_cipher.Destroy;
  393. begin
  394.   if fInitialized then
  395.     Burn;
  396.   inherited Destroy;
  397. end;
  398.  
  399.  
  400. {** TDCP_blockcipher **********************************************************}
  401.  
  402. procedure TDCP_blockcipher.Encrypt(const Indata; var Outdata; Size: longword);
  403. begin
  404.   case fCipherMode of
  405.     cmCBC: EncryptCBC(Indata,Outdata,Size);
  406.     cmCFB8bit: EncryptCFB8bit(Indata,Outdata,Size);
  407.     cmCFBblock: EncryptCFBblock(Indata,Outdata,Size);
  408.     cmOFB: EncryptOFB(Indata,Outdata,Size);
  409.     cmCTR: EncryptCTR(Indata,Outdata,Size);
  410.   end;
  411. end;
  412.  
  413. function TDCP_blockcipher.EncryptString(const Str: string): string;
  414. begin
  415.   SetLength(Result,Length(Str));
  416.   EncryptCFB8bit(Str[1],Result[1],Length(Str));
  417.   Result:= Base64EncodeStr(Result);
  418. end;
  419.  
  420. function TDCP_blockcipher.DecryptString(const Str: string): string;
  421. begin
  422.   Result:= Base64DecodeStr(Str);
  423.   DecryptCFB8bit(Result[1],Result[1],Length(Result));
  424. end;
  425.  
  426. procedure TDCP_blockcipher.Decrypt(const Indata; var Outdata; Size: longword);
  427. begin
  428.   case fCipherMode of
  429.     cmCBC: DecryptCBC(Indata,Outdata,Size);
  430.     cmCFB8bit: DecryptCFB8bit(Indata,Outdata,Size);
  431.     cmCFBblock: DecryptCFBblock(Indata,Outdata,Size);
  432.     cmOFB: DecryptOFB(Indata,Outdata,Size);
  433.     cmCTR: DecryptCTR(Indata,Outdata,Size);
  434.   end;
  435. end;
  436.  
  437. constructor TDCP_blockcipher.Create(AOwner: TComponent);
  438. begin
  439.   inherited Create(AOwner);
  440.   fCipherMode:= cmCBC;
  441. end;
  442.  
  443.  
  444. {** Helpher functions *********************************************************}
  445. procedure XorBlock(var InData1, InData2; Size: longword);
  446. var
  447.   i: longword;
  448. begin
  449.   for i:= 1 to Size do
  450.     Pbyte(longword(@InData1)+i-1)^:= Pbyte(longword(@InData1)+i-1)^ xor Pbyte(longword(@InData2)+i-1)^;
  451. end;
  452.  
  453. end.
  454.  
  455.