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

  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of DES and Triple DES *******************}
  5. {* Based on C source code by Eric Young ***************************************}
  6. {******************************************************************************}
  7. {* Copyright (c) 1999-2002 David Barton                                       *}
  8. {* Permission is hereby granted, free of charge, to any person obtaining a    *}
  9. {* copy of this software and associated documentation files (the "Software"), *}
  10. {* to deal in the Software without restriction, including without limitation  *}
  11. {* the rights to use, copy, modify, merge, publish, distribute, sublicense,   *}
  12. {* and/or sell copies of the Software, and to permit persons to whom the      *}
  13. {* Software is furnished to do so, subject to the following conditions:       *}
  14. {*                                                                            *}
  15. {* The above copyright notice and this permission notice shall be included in *}
  16. {* all copies or substantial portions of the Software.                        *}
  17. {*                                                                            *}
  18. {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *}
  19. {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *}
  20. {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *}
  21. {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *}
  22. {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    *}
  23. {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        *}
  24. {* DEALINGS IN THE SOFTWARE.                                                  *}
  25. {******************************************************************************}
  26. {******************************************************************************}
  27. {*       This implementation of DES is based on the C implementation by       *}
  28. {*                       Eric Young (eay@mincom.oz.au)                        *}
  29. {******************************************************************************}
  30. {*    DES takes a 64bit key and discards every 8th bit (56bit effectively)    *}
  31. {*    3DES takes either a <= 128bit key and uses one key twice or takes a     *}
  32. {*     <= 192bit key and uses each once (again discarding every 8th bit)      *}
  33. {******************************************************************************}
  34. unit DCPdes;
  35.  
  36. interface
  37. uses
  38.   Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  39.  
  40. type
  41.   TDCP_customdes= class(TDCP_blockcipher64)
  42.   protected
  43.     procedure DoInit(KeyB: PByteArray; KeyData: PDWordArray);
  44.     procedure EncryptBlock(const InData; var OutData; KeyData: PDWordArray);
  45.     procedure DecryptBlock(const InData; var OutData; KeyData: PDWordArray);
  46.   end;
  47.  
  48. type
  49.   TDCP_des= class(TDCP_customdes)
  50.   protected
  51.     KeyData: array[0..31] of dword;
  52.     procedure InitKey(const Key; Size: longword); override;
  53.   public
  54.     class function GetId: integer; override;
  55.     class function GetAlgorithm: string; override;
  56.     class function GetMaxKeySize: integer; override;
  57.     class function SelfTest: boolean; override;
  58.     procedure Burn; override;
  59.     procedure EncryptECB(const InData; var OutData); override;
  60.     procedure DecryptECB(const InData; var OutData); override;
  61.   end;
  62.  
  63.   TDCP_3des= class(TDCP_customdes)
  64.   protected
  65.     KeyData: array[0..2,0..31] of dword;
  66.     procedure InitKey(const Key; Size: longword); override;
  67.   public
  68.     class function GetId: integer; override;
  69.     class function GetAlgorithm: string; override;
  70.     class function GetMaxKeySize: integer; override;
  71.     class function SelfTest: boolean; override;
  72.     procedure Burn; override;
  73.     procedure EncryptECB(const InData; var OutData); override;
  74.     procedure DecryptECB(const InData; var OutData); override;
  75.   end;
  76.  
  77. {******************************************************************************}
  78. {******************************************************************************}
  79. implementation
  80. {$R-}{$Q-}
  81.  
  82. {$I DCPdes.inc}
  83.  
  84. procedure hperm_op(var a, t: dword; n, m: dword);
  85. begin
  86.   t:= ((a shl (16 - n)) xor a) and m;
  87.   a:= a xor t xor (t shr (16 - n));
  88. end;
  89.  
  90. procedure perm_op(var a, b, t: dword; n, m: dword);
  91. begin
  92.   t:= ((a shr n) xor b) and m;
  93.   b:= b xor t;
  94.   a:= a xor (t shl n);
  95. end;
  96.  
  97. procedure TDCP_customdes.DoInit(KeyB: PByteArray; KeyData: PDwordArray);
  98. var
  99.   c, d, t, s, t2, i: dword;
  100. begin
  101.   c:= KeyB^[0] or (KeyB^[1] shl 8) or (KeyB^[2] shl 16) or (KeyB^[3] shl 24);
  102.   d:= KeyB^[4] or (KeyB^[5] shl 8) or (KeyB^[6] shl 16) or (KeyB^[7] shl 24);
  103.   perm_op(d,c,t,4,$0f0f0f0f);
  104.   hperm_op(c,t,dword(-2),$cccc0000);
  105.   hperm_op(d,t,dword(-2),$cccc0000);
  106.   perm_op(d,c,t,1,$55555555);
  107.   perm_op(c,d,t,8,$00ff00ff);
  108.   perm_op(d,c,t,1,$55555555);
  109.   d:= ((d and $ff) shl 16) or (d and $ff00) or ((d and $ff0000) shr 16) or
  110.         ((c and $f0000000) shr 4);
  111.   c:= c and $fffffff;
  112.   for i:= 0 to 15 do
  113.   begin
  114.     if shifts2[i]<> 0 then
  115.     begin
  116.       c:= ((c shr 2) or (c shl 26));
  117.       d:= ((d shr 2) or (d shl 26));
  118.     end
  119.     else
  120.     begin
  121.       c:= ((c shr 1) or (c shl 27));
  122.       d:= ((d shr 1) or (d shl 27));
  123.     end;
  124.     c:= c and $fffffff;
  125.     d:= d and $fffffff;
  126.     s:= des_skb[0,c and $3f] or
  127.         des_skb[1,((c shr  6) and $03) or ((c shr  7) and $3c)] or
  128.         des_skb[2,((c shr 13) and $0f) or ((c shr 14) and $30)] or
  129.         des_skb[3,((c shr 20) and $01) or ((c shr 21) and $06) or ((c shr 22) and $38)];
  130.     t:= des_skb[4,d and $3f] or
  131.         des_skb[5,((d shr  7) and $03) or ((d shr  8) and $3c)] or
  132.         des_skb[6, (d shr 15) and $3f                         ] or
  133.         des_skb[7,((d shr 21) and $0f) or ((d shr 22) and $30)];
  134.     t2:= ((t shl 16) or (s and $ffff));
  135.     KeyData^[(i shl 1)]:= ((t2 shl 2) or (t2 shr 30));
  136.     t2:= ((s shr 16) or (t and $ffff0000));
  137.     KeyData^[(i shl 1)+1]:= ((t2 shl 6) or (t2 shr 26));
  138.   end;
  139. end;
  140.  
  141. procedure TDCP_customdes.EncryptBlock(const InData; var OutData; KeyData: PDWordArray);
  142. var
  143.   l, r, t, u: dword;
  144.   i: longint;
  145. begin
  146.   r:= PDword(@InData)^;
  147.   l:= PDword(dword(@InData)+4)^;
  148.   t:= ((l shr 4) xor r) and $0f0f0f0f;
  149.   r:= r xor t;
  150.   l:= l xor (t shl 4);
  151.   t:= ((r shr 16) xor l) and $0000ffff;
  152.   l:= l xor t;
  153.   r:= r xor (t shl 16);
  154.   t:= ((l shr 2) xor r) and $33333333;
  155.   r:= r xor t;
  156.   l:= l xor (t shl 2);
  157.   t:= ((r shr 8) xor l) and $00ff00ff;
  158.   l:= l xor t;
  159.   r:= r xor (t shl 8);
  160.   t:= ((l shr 1) xor r) and $55555555;
  161.   r:= r xor t;
  162.   l:= l xor (t shl 1);
  163.   r:= (r shr 29) or (r shl 3);
  164.   l:= (l shr 29) or (l shl 3);
  165.   i:= 0;
  166.   while i< 32 do
  167.   begin
  168.     u:= r xor KeyData^[i  ];
  169.     t:= r xor KeyData^[i+1];
  170.     t:= (t shr 4) or (t shl 28);
  171.     l:= l xor des_SPtrans[0,(u shr  2) and $3f] xor
  172.               des_SPtrans[2,(u shr 10) and $3f] xor
  173.               des_SPtrans[4,(u shr 18) and $3f] xor
  174.               des_SPtrans[6,(u shr 26) and $3f] xor
  175.               des_SPtrans[1,(t shr  2) and $3f] xor
  176.               des_SPtrans[3,(t shr 10) and $3f] xor
  177.               des_SPtrans[5,(t shr 18) and $3f] xor
  178.               des_SPtrans[7,(t shr 26) and $3f];
  179.     u:= l xor KeyData^[i+2];
  180.     t:= l xor KeyData^[i+3];
  181.     t:= (t shr 4) or (t shl 28);
  182.     r:= r xor des_SPtrans[0,(u shr  2) and $3f] xor
  183.               des_SPtrans[2,(u shr 10) and $3f] xor
  184.               des_SPtrans[4,(u shr 18) and $3f] xor
  185.               des_SPtrans[6,(u shr 26) and $3f] xor
  186.               des_SPtrans[1,(t shr  2) and $3f] xor
  187.               des_SPtrans[3,(t shr 10) and $3f] xor
  188.               des_SPtrans[5,(t shr 18) and $3f] xor
  189.               des_SPtrans[7,(t shr 26) and $3f];
  190.     u:= r xor KeyData^[i+4];
  191.     t:= r xor KeyData^[i+5];
  192.     t:= (t shr 4) or (t shl 28);
  193.     l:= l xor des_SPtrans[0,(u shr  2) and $3f] xor
  194.               des_SPtrans[2,(u shr 10) and $3f] xor
  195.               des_SPtrans[4,(u shr 18) and $3f] xor
  196.               des_SPtrans[6,(u shr 26) and $3f] xor
  197.               des_SPtrans[1,(t shr  2) and $3f] xor
  198.               des_SPtrans[3,(t shr 10) and $3f] xor
  199.               des_SPtrans[5,(t shr 18) and $3f] xor
  200.               des_SPtrans[7,(t shr 26) and $3f];
  201.     u:= l xor KeyData^[i+6];
  202.     t:= l xor KeyData^[i+7];
  203.     t:= (t shr 4) or (t shl 28);
  204.     r:= r xor des_SPtrans[0,(u shr  2) and $3f] xor
  205.               des_SPtrans[2,(u shr 10) and $3f] xor
  206.               des_SPtrans[4,(u shr 18) and $3f] xor
  207.               des_SPtrans[6,(u shr 26) and $3f] xor
  208.               des_SPtrans[1,(t shr  2) and $3f] xor
  209.               des_SPtrans[3,(t shr 10) and $3f] xor
  210.               des_SPtrans[5,(t shr 18) and $3f] xor
  211.               des_SPtrans[7,(t shr 26) and $3f];
  212.     Inc(i,8);
  213.   end;
  214.   r:= (r shr 3) or (r shl 29);
  215.   l:= (l shr 3) or (l shl 29);
  216.   t:= ((r shr 1) xor l) and $55555555;
  217.   l:= l xor t;
  218.   r:= r xor (t shl 1);
  219.   t:= ((l shr 8) xor r) and $00ff00ff;
  220.   r:= r xor t;
  221.   l:= l xor (t shl 8);
  222.   t:= ((r shr 2) xor l) and $33333333;
  223.   l:= l xor t;
  224.   r:= r xor (t shl 2);
  225.   t:= ((l shr 16) xor r) and $0000ffff;
  226.   r:= r xor t;
  227.   l:= l xor (t shl 16);
  228.   t:= ((r shr 4) xor l) and $0f0f0f0f;
  229.   l:= l xor t;
  230.   r:= r xor (t shl 4);
  231.   PDword(@OutData)^:= l;
  232.   PDword(dword(@OutData)+4)^:= r;
  233. end;
  234.  
  235. procedure TDCP_customdes.DecryptBlock(const InData; var OutData; KeyData: PDWordArray);
  236. var
  237.   l, r, t, u: dword;
  238.   i: longint;
  239. begin
  240.   r:= PDword(@InData)^;
  241.   l:= PDword(dword(@InData)+4)^;
  242.   t:= ((l shr 4) xor r) and $0f0f0f0f;
  243.   r:= r xor t;
  244.   l:= l xor (t shl 4);
  245.   t:= ((r shr 16) xor l) and $0000ffff;
  246.   l:= l xor t;
  247.   r:= r xor (t shl 16);
  248.   t:= ((l shr 2) xor r) and $33333333;
  249.   r:= r xor t;
  250.   l:= l xor (t shl 2);
  251.   t:= ((r shr 8) xor l) and $00ff00ff;
  252.   l:= l xor t;
  253.   r:= r xor (t shl 8);
  254.   t:= ((l shr 1) xor r) and $55555555;
  255.   r:= r xor t;
  256.   l:= l xor (t shl 1);
  257.   r:= (r shr 29) or (r shl 3);
  258.   l:= (l shr 29) or (l shl 3);
  259.   i:= 30;
  260.   while i> 0 do
  261.   begin
  262.     u:= r xor KeyData^[i  ];
  263.     t:= r xor KeyData^[i+1];
  264.     t:= (t shr 4) or (t shl 28);
  265.     l:= l xor des_SPtrans[0,(u shr  2) and $3f] xor
  266.               des_SPtrans[2,(u shr 10) and $3f] xor
  267.               des_SPtrans[4,(u shr 18) and $3f] xor
  268.               des_SPtrans[6,(u shr 26) and $3f] xor
  269.               des_SPtrans[1,(t shr  2) and $3f] xor
  270.               des_SPtrans[3,(t shr 10) and $3f] xor
  271.               des_SPtrans[5,(t shr 18) and $3f] xor
  272.               des_SPtrans[7,(t shr 26) and $3f];
  273.     u:= l xor KeyData^[i-2];
  274.     t:= l xor KeyData^[i-1];
  275.     t:= (t shr 4) or (t shl 28);
  276.     r:= r xor des_SPtrans[0,(u shr  2) and $3f] xor
  277.               des_SPtrans[2,(u shr 10) and $3f] xor
  278.               des_SPtrans[4,(u shr 18) and $3f] xor
  279.               des_SPtrans[6,(u shr 26) and $3f] xor
  280.               des_SPtrans[1,(t shr  2) and $3f] xor
  281.               des_SPtrans[3,(t shr 10) and $3f] xor
  282.               des_SPtrans[5,(t shr 18) and $3f] xor
  283.               des_SPtrans[7,(t shr 26) and $3f];
  284.     u:= r xor KeyData^[i-4];
  285.     t:= r xor KeyData^[i-3];
  286.     t:= (t shr 4) or (t shl 28);
  287.     l:= l xor des_SPtrans[0,(u shr  2) and $3f] xor
  288.               des_SPtrans[2,(u shr 10) and $3f] xor
  289.               des_SPtrans[4,(u shr 18) and $3f] xor
  290.               des_SPtrans[6,(u shr 26) and $3f] xor
  291.               des_SPtrans[1,(t shr  2) and $3f] xor
  292.               des_SPtrans[3,(t shr 10) and $3f] xor
  293.               des_SPtrans[5,(t shr 18) and $3f] xor
  294.               des_SPtrans[7,(t shr 26) and $3f];
  295.     u:= l xor KeyData^[i-6];
  296.     t:= l xor KeyData^[i-5];
  297.     t:= (t shr 4) or (t shl 28);
  298.     r:= r xor des_SPtrans[0,(u shr  2) and $3f] xor
  299.               des_SPtrans[2,(u shr 10) and $3f] xor
  300.               des_SPtrans[4,(u shr 18) and $3f] xor
  301.               des_SPtrans[6,(u shr 26) and $3f] xor
  302.               des_SPtrans[1,(t shr  2) and $3f] xor
  303.               des_SPtrans[3,(t shr 10) and $3f] xor
  304.               des_SPtrans[5,(t shr 18) and $3f] xor
  305.               des_SPtrans[7,(t shr 26) and $3f];
  306.     Dec(i,8);
  307.   end;
  308.   r:= (r shr 3) or (r shl 29);
  309.   l:= (l shr 3) or (l shl 29);
  310.   t:= ((r shr 1) xor l) and $55555555;
  311.   l:= l xor t;
  312.   r:= r xor (t shl 1);
  313.   t:= ((l shr 8) xor r) and $00ff00ff;
  314.   r:= r xor t;
  315.   l:= l xor (t shl 8);
  316.   t:= ((r shr 2) xor l) and $33333333;
  317.   l:= l xor t;
  318.   r:= r xor (t shl 2);
  319.   t:= ((l shr 16) xor r) and $0000ffff;
  320.   r:= r xor t;
  321.   l:= l xor (t shl 16);
  322.   t:= ((r shr 4) xor l) and $0f0f0f0f;
  323.   l:= l xor t;
  324.   r:= r xor (t shl 4);
  325.   PDword(@OutData)^:= l;
  326.   PDword(dword(@OutData)+4)^:= r;
  327. end;
  328.  
  329. class function TDCP_des.GetMaxKeySize: integer;
  330. begin
  331.   Result:= 64;
  332. end;
  333.  
  334. class function TDCP_des.GetID: integer;
  335. begin
  336.   Result:= DCP_des;
  337. end;
  338.  
  339. class function TDCP_des.GetAlgorithm: string;
  340. begin
  341.   Result:= 'DES';
  342. end;
  343.  
  344. class function TDCP_des.SelfTest: boolean;
  345. const
  346.   InData1: array[0..7] of byte=
  347.     ($07,$56,$D8,$E0,$77,$47,$61,$D2);
  348.   OutData1: array[0..7] of byte=
  349.     ($0C,$D3,$DA,$02,$00,$21,$DC,$09);
  350.   Key1: array[0..7] of byte=
  351.     ($01,$70,$F1,$75,$46,$8F,$B5,$E6);
  352.   InData2: array[0..7] of byte=
  353.     ($48,$0D,$39,$00,$6E,$E7,$62,$F2);
  354.   OutData2: array[0..7] of byte=
  355.     ($A1,$F9,$91,$55,$41,$02,$0B,$56);
  356.   Key2: array[0..7] of byte=
  357.     ($02,$58,$16,$16,$46,$29,$B0,$07);
  358. var
  359.   Cipher: TDCP_des;
  360.   Data: array[0..7] of byte;
  361. begin
  362.   Cipher:= TDCP_des.Create(nil);
  363.   Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  364.   Cipher.EncryptECB(InData1,Data);
  365.   Result:= boolean(CompareMem(@Data,@OutData1,Sizeof(Data)));
  366.   Cipher.DecryptECB(Data,Data);
  367.   Result:= Result and boolean(CompareMem(@Data,@InData1,Sizeof(Data)));
  368.   Cipher.Burn;
  369.   Cipher.Init(Key2,Sizeof(Key2)*8,nil);
  370.   Cipher.EncryptECB(InData2,Data);
  371.   Result:= Result and boolean(CompareMem(@Data,@OutData2,Sizeof(Data)));
  372.   Cipher.DecryptECB(Data,Data);
  373.   Result:= Result and boolean(CompareMem(@Data,@InData2,Sizeof(Data)));
  374.   Cipher.Burn;
  375.   Cipher.Free;
  376. end;
  377.  
  378. procedure TDCP_des.InitKey(const Key; Size: longword);
  379. var
  380.   KeyB: array[0..7] of byte;
  381. begin
  382.   FillChar(KeyB,Sizeof(KeyB),0);
  383.   Move(Key,KeyB,Size div 8);
  384.   DoInit(@KeyB,@KeyData);
  385. end;
  386.  
  387. procedure TDCP_des.Burn;
  388. begin
  389.   FillChar(KeyData,Sizeof(KeyData),0);
  390.   inherited Burn;
  391. end;
  392.  
  393. procedure TDCP_des.EncryptECB(const InData; var OutData);
  394. begin
  395.   if not fInitialized then
  396.     raise EDCP_blockcipher.Create('Cipher not initialized');
  397.   EncryptBlock(InData,OutData,@KeyData);
  398. end;
  399.  
  400. procedure TDCP_des.DecryptECB(const InData; var OutData);
  401. begin
  402.   if not fInitialized then
  403.     raise EDCP_blockcipher.Create('Cipher not initialized');
  404.   DecryptBlock(InData,OutData,@KeyData);
  405. end;
  406.  
  407. {******************************************************************************}
  408. class function TDCP_3des.GetMaxKeySize: integer;
  409. begin
  410.   Result:= 192;
  411. end;
  412.  
  413. class function TDCP_3des.GetID: integer;
  414. begin
  415.   Result:= DCP_3des;
  416. end;
  417.  
  418. class function TDCP_3des.GetAlgorithm: string;
  419. begin
  420.   Result:= '3DES';
  421. end;
  422.  
  423. class function TDCP_3des.SelfTest: boolean;
  424. const
  425.   Key: array[0..23] of byte=
  426.     ($01,$23,$45,$67,$89,$ab,$cd,$ef,$fe,$dc,$ba,$98,
  427.      $76,$54,$32,$10,$89,$ab,$cd,$ef,$01,$23,$45,$67);
  428.   PlainText: array[0..7] of byte=
  429.     ($01,$23,$45,$67,$89,$ab,$cd,$e7);
  430.   CipherText: array[0..7] of byte=
  431.     ($de,$0b,$7c,$06,$ae,$5e,$0e,$d5);
  432. var
  433.   Cipher: TDCP_3des;
  434.   Block: array[0..7] of byte;
  435. begin
  436.   Cipher:= TDCP_3des.Create(nil);
  437.   Cipher.Init(Key,Sizeof(Key)*8,nil);
  438.   Cipher.EncryptECB(PlainText,Block);
  439.   Result:= CompareMem(@Block,@CipherText,Sizeof(CipherText));
  440.   Cipher.DecryptECB(Block,Block);
  441.   Result:= Result and CompareMem(@Block,@PlainText,Sizeof(PlainText));
  442.   Cipher.Free;
  443. end;
  444.  
  445. procedure TDCP_3des.InitKey(const Key; Size: longword);
  446. var
  447.   KeyB: array[0..2,0..7] of byte;
  448. begin
  449.   FillChar(KeyB,Sizeof(KeyB),0);
  450.   Move(Key,KeyB,Size div 8);
  451.   DoInit(@KeyB[0],@KeyData[0]);
  452.   DoInit(@KeyB[1],@KeyData[1]);
  453.   if Size> 128 then
  454.     DoInit(@KeyB[2],@KeyData[2])
  455.   else
  456.     Move(KeyData[0],KeyData[2],128);
  457. end;
  458.  
  459. procedure TDCP_3des.Burn;
  460. begin
  461.   FillChar(KeyData,Sizeof(KeyData),0);
  462.   inherited Burn;
  463. end;
  464.  
  465. procedure TDCP_3des.EncryptECB(const InData; var OutData);
  466. begin
  467.   if not fInitialized then
  468.     raise EDCP_blockcipher.Create('Cipher not initialized');
  469.   EncryptBlock(InData,OutData,@KeyData[0]);
  470.   DecryptBlock(OutData,OutData,@KeyData[1]);
  471.   EncryptBlock(OutData,OutData,@KeyData[2]);
  472. end;
  473.  
  474. procedure TDCP_3des.DecryptECB(const InData; var OutData);
  475. begin
  476.   if not fInitialized then
  477.     raise EDCP_blockcipher.Create('Cipher not initialized');
  478.   DecryptBlock(InData,OutData,@KeyData[2]);
  479.   EncryptBlock(OutData,OutData,@KeyData[1]);
  480.   DecryptBlock(OutData,OutData,@KeyData[0]);
  481. end;
  482.  
  483.  
  484. end.
  485.