DCPrc4.pas 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of RC4 **********************************}
  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 DCPrc4;
  26. interface
  27. uses
  28. Classes, Sysutils, DCPcrypt2, DCPconst;
  29. type
  30. TDCP_rc4= class(TDCP_cipher)
  31. protected
  32. KeyData, KeyOrg: array[0..255] of byte;
  33. public
  34. class function GetID: integer; override;
  35. class function GetAlgorithm: string; override;
  36. class function GetMaxKeySize: integer; override;
  37. class function SelfTest: boolean; override;
  38. procedure Init(const Key; Size: longword; InitVector: pointer); override;
  39. procedure Reset; override;
  40. procedure Burn; override;
  41. procedure Encrypt(const InData; var OutData; Size: longword); override;
  42. procedure Decrypt(const InData; var OutData; Size: longword); override;
  43. end;
  44. {******************************************************************************}
  45. {******************************************************************************}
  46. implementation
  47. {$R-}{$Q-}
  48. class function TDCP_rc4.GetID: integer;
  49. begin
  50. Result:= DCP_rc4;
  51. end;
  52. class function TDCP_rc4.GetAlgorithm: string;
  53. begin
  54. Result:= 'RC4';
  55. end;
  56. class function TDCP_rc4.GetMaxKeySize: integer;
  57. begin
  58. Result:= 2048;
  59. end;
  60. class function TDCP_rc4.SelfTest: boolean;
  61. const
  62. Key1: array[0..4] of byte= ($61,$8A,$63,$D2,$FB);
  63. InData1: array[0..4] of byte= ($DC,$EE,$4C,$F9,$2C);
  64. OutData1: array[0..4] of byte= ($F1,$38,$29,$C9,$DE);
  65. var
  66. Cipher: TDCP_rc4;
  67. Data: array[0..4] of byte;
  68. begin
  69. Cipher:= TDCP_rc4.Create(nil);
  70. Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  71. Cipher.Encrypt(InData1,Data,Sizeof(Data));
  72. Result:= boolean(CompareMem(@Data,@OutData1,Sizeof(Data)));
  73. Cipher.Reset;
  74. Cipher.Decrypt(Data,Data,Sizeof(Data));
  75. Result:= boolean(CompareMem(@Data,@InData1,Sizeof(Data))) and Result;
  76. Cipher.Burn;
  77. Cipher.Free;
  78. end;
  79. procedure TDCP_rc4.Init(const Key; Size: longword; InitVector: pointer);
  80. var
  81. i, j, t: longword;
  82. xKey: array[0..255] of byte;
  83. begin
  84. if fInitialized then
  85. Burn;
  86. inherited Init(Key,Size,nil);
  87. Size:= Size div 8;
  88. i:= 0;
  89. while i< 255 do
  90. begin
  91. KeyData[i]:= i;
  92. xKey[i]:= PByte(longword(@Key)+(i mod Size))^;
  93. KeyData[i+1]:= i+1;
  94. xKey[i+1]:= PByte(longword(@Key)+((i+1) mod Size))^;
  95. KeyData[i+2]:= i+2;
  96. xKey[i+2]:= PByte(longword(@Key)+((i+2) mod Size))^;
  97. KeyData[i+3]:= i+3;
  98. xKey[i+3]:= PByte(longword(@Key)+((i+3) mod Size))^;
  99. KeyData[i+4]:= i+4;
  100. xKey[i+4]:= PByte(longword(@Key)+((i+4) mod Size))^;
  101. KeyData[i+5]:= i+5;
  102. xKey[i+5]:= PByte(longword(@Key)+((i+5) mod Size))^;
  103. KeyData[i+6]:= i+6;
  104. xKey[i+6]:= PByte(longword(@Key)+((i+6) mod Size))^;
  105. KeyData[i+7]:= i+7;
  106. xKey[i+7]:= PByte(longword(@Key)+((i+7) mod Size))^;
  107. Inc(i,8);
  108. end;
  109. j:= 0;
  110. i:= 0;
  111. while i< 255 do
  112. begin
  113. j:= (j+KeyData[i]+xKey[i]) and $FF;
  114. t:= KeyData[i];
  115. KeyData[i]:= KeyData[j];
  116. KeyData[j]:= t;
  117. j:= (j+KeyData[i+1]+xKey[i+1]) and $FF;
  118. t:= KeyData[i+1];
  119. KeyData[i+1]:= KeyData[j];
  120. KeyData[j]:= t;
  121. j:= (j+KeyData[i+2]+xKey[i+2]) and $FF;
  122. t:= KeyData[i+2];
  123. KeyData[i+2]:= KeyData[j];
  124. KeyData[j]:= t;
  125. j:= (j+KeyData[i+3]+xKey[i+3]) and $FF;
  126. t:= KeyData[i+3];
  127. KeyData[i+3]:= KeyData[j];
  128. KeyData[j]:= t;
  129. j:= (j+KeyData[i+4]+xKey[i+4]) and $FF;
  130. t:= KeyData[i+4];
  131. KeyData[i+4]:= KeyData[j];
  132. KeyData[j]:= t;
  133. j:= (j+KeyData[i+5]+xKey[i+5]) and $FF;
  134. t:= KeyData[i+5];
  135. KeyData[i+5]:= KeyData[j];
  136. KeyData[j]:= t;
  137. j:= (j+KeyData[i+6]+xKey[i+6]) and $FF;
  138. t:= KeyData[i+6];
  139. KeyData[i+6]:= KeyData[j];
  140. KeyData[j]:= t;
  141. j:= (j+KeyData[i+7]+xKey[i+7]) and $FF;
  142. t:= KeyData[i+7];
  143. KeyData[i+7]:= KeyData[j];
  144. KeyData[j]:= t;
  145. Inc(i,8);
  146. end;
  147. Move(KeyData,KeyOrg,Sizeof(KeyOrg));
  148. end;
  149. procedure TDCP_rc4.Reset;
  150. begin
  151. Move(KeyOrg,KeyData,Sizeof(KeyData));
  152. end;
  153. procedure TDCP_rc4.Burn;
  154. begin
  155. FillChar(KeyOrg,Sizeof(KeyOrg),$FF);
  156. FillChar(KeyData,Sizeof(KeyData),$FF);
  157. inherited Burn;
  158. end;
  159. procedure TDCP_rc4.Encrypt(const InData; var OutData; Size: longword);
  160. var
  161. i, j, t, k: longword;
  162. begin
  163. if not fInitialized then
  164. raise EDCP_cipher.Create('Cipher not initialized');
  165. i:= 0; j:= 0;
  166. for k:= 0 to Size-1 do
  167. begin
  168. i:= (i + 1) and $FF;
  169. t:= KeyData[i];
  170. j:= (j + t) and $FF;
  171. KeyData[i]:= KeyData[j];
  172. KeyData[j]:= t;
  173. t:= (t + KeyData[i]) and $FF;
  174. Pbytearray(@OutData)^[k]:= Pbytearray(@InData)^[k] xor KeyData[t];
  175. end;
  176. end;
  177. procedure TDCP_rc4.Decrypt(const InData; var OutData; Size: longword);
  178. var
  179. i, j, t, k: longword;
  180. begin
  181. if not fInitialized then
  182. raise EDCP_cipher.Create('Cipher not initialized');
  183. i:= 0; j:= 0;
  184. for k:= 0 to Size-1 do
  185. begin
  186. i:= (i + 1) and $FF;
  187. t:= KeyData[i];
  188. j:= (j + t) and $FF;
  189. KeyData[i]:= KeyData[j];
  190. KeyData[j]:= t;
  191. t:= (t + KeyData[i]) and $FF;
  192. Pbytearray(@OutData)^[k]:= Pbytearray(@InData)^[k] xor KeyData[t];
  193. end;
  194. end;
  195. end.