DCPgost.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of Gost *********************************}
  5. {******************************************************************************}
  6. {******************************************************************************}
  7. {* !!WARNING!! !!WARNING!! !!WARNING!!!!WARNING!! !!WARNING!! !!WARNING!! *}
  8. {* *}
  9. {* I am not sure if this is compatible with the actual GOST standard *}
  10. {* as a result, use this implementation with extreme caution. *}
  11. {* *}
  12. {* !!WARNING!! !!WARNING!! !!WARNING!!!!WARNING!! !!WARNING!! !!WARNING!! *}
  13. {******************************************************************************}
  14. {******************************************************************************}
  15. {* Copyright (c) 1999-2002 David Barton *}
  16. {* Permission is hereby granted, free of charge, to any person obtaining a *}
  17. {* copy of this software and associated documentation files (the "Software"), *}
  18. {* to deal in the Software without restriction, including without limitation *}
  19. {* the rights to use, copy, modify, merge, publish, distribute, sublicense, *}
  20. {* and/or sell copies of the Software, and to permit persons to whom the *}
  21. {* Software is furnished to do so, subject to the following conditions: *}
  22. {* *}
  23. {* The above copyright notice and this permission notice shall be included in *}
  24. {* all copies or substantial portions of the Software. *}
  25. {* *}
  26. {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *}
  27. {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *}
  28. {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *}
  29. {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *}
  30. {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *}
  31. {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *}
  32. {* DEALINGS IN THE SOFTWARE. *}
  33. {******************************************************************************}
  34. unit DCPgost;
  35. interface
  36. uses
  37. Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  38. type
  39. TDCP_gost= class(TDCP_blockcipher64)
  40. protected
  41. KeyData: array[0..7] of DWord;
  42. procedure InitKey(const Key; Size: longword); override;
  43. public
  44. class function GetID: integer; override;
  45. class function GetAlgorithm: string; override;
  46. class function GetMaxKeySize: integer; override;
  47. class function SelfTest: boolean; override;
  48. procedure Burn; override;
  49. procedure EncryptECB(const InData; var OutData); override;
  50. procedure DecryptECB(const InData; var OutData); override;
  51. end;
  52. {******************************************************************************}
  53. {******************************************************************************}
  54. implementation
  55. {$R-}{$Q-}
  56. {$I DCPgost.inc}
  57. class function TDCP_gost.GetMaxKeySize: integer;
  58. begin
  59. Result:= 256;
  60. end;
  61. class function TDCP_gost.GetID: integer;
  62. begin
  63. Result:= DCP_gost;
  64. end;
  65. class function TDCP_gost.GetAlgorithm: string;
  66. begin
  67. Result:= 'Gost';
  68. end;
  69. class function TDCP_gost.SelfTest: boolean;
  70. const
  71. Key1: array[0..31] of byte=
  72. ($BE,$5E,$C2,$00,$6C,$FF,$9D,$CF,$52,$35,$49,$59,$F1,$FF,$0C,$BF,
  73. $E9,$50,$61,$B5,$A6,$48,$C1,$03,$87,$06,$9C,$25,$99,$7C,$06,$72);
  74. InData1: array[0..7] of byte=
  75. ($0D,$F8,$28,$02,$B7,$41,$A2,$92);
  76. OutData1: array[0..7] of byte=
  77. ($07,$F9,$02,$7D,$F7,$F7,$DF,$89);
  78. Key2: array[0..31] of byte=
  79. ($B3,$85,$27,$2A,$C8,$D7,$2A,$5A,$8B,$34,$4B,$C8,$03,$63,$AC,$4D,
  80. $09,$BF,$58,$F4,$1F,$54,$06,$24,$CB,$CB,$8F,$DC,$F5,$53,$07,$D7);
  81. InData2: array[0..7] of byte=
  82. ($13,$54,$EE,$9C,$0A,$11,$CD,$4C);
  83. OutData2: array[0..7] of byte=
  84. ($4F,$B5,$05,$36,$F9,$60,$A7,$B1);
  85. var
  86. Block: array[0..7] of byte;
  87. Cipher: TDCP_gost;
  88. begin
  89. Cipher:= TDCP_gost.Create(nil);
  90. Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  91. Cipher.EncryptECB(InData1,Block);
  92. Result:= boolean(CompareMem(@Block,@OutData1,8));
  93. Cipher.DecryptECB(Block,Block);
  94. Cipher.Burn;
  95. Result:= Result and boolean(CompareMem(@Block,@InData1,8));
  96. Cipher.Init(Key2,Sizeof(Key2)*8,nil);
  97. Cipher.EncryptECB(InData2,Block);
  98. Result:= Result and boolean(CompareMem(@Block,@OutData2,8));
  99. Cipher.DecryptECB(Block,Block);
  100. Cipher.Burn;
  101. Result:= Result and boolean(CompareMem(@Block,@InData2,8));
  102. Cipher.Free;
  103. end;
  104. procedure TDCP_gost.InitKey(const Key; Size: longword);
  105. var
  106. i: longword;
  107. userkey: array[0..31] of byte;
  108. begin
  109. Size:= Size div 8;
  110. FillChar(userkey,Sizeof(userkey),0);
  111. Move(Key,userkey,Size);
  112. for i:= 0 to 7 do
  113. KeyData[i]:= (dword(UserKey[4*i+3]) shl 24) or (dword(UserKey[4*i+2]) shl 16) or
  114. (dword(UserKey[4*i+1]) shl 8) or (dword(UserKey[4*i+0]));
  115. end;
  116. procedure TDCP_gost.Burn;
  117. begin
  118. FillChar(KeyData,Sizeof(KeyData),0);
  119. inherited Burn;
  120. end;
  121. procedure TDCP_gost.EncryptECB(const InData; var OutData);
  122. var
  123. n1, n2: DWord;
  124. i: longword;
  125. begin
  126. if not fInitialized then
  127. raise EDCP_blockcipher.Create('Cipher not initialized');
  128. n1:= PDword(@InData)^;
  129. n2:= PDword(dword(@InData)+4)^;
  130. for i:= 0 to 2 do
  131. begin
  132. n2:= n2 xor (sTable[3,(n1+KeyData[0]) shr 24] xor sTable[2,((n1+KeyData[0]) shr 16) and $FF]
  133. xor sTable[1,((n1+KeyData[0]) shr 8) and $FF] xor sTable[0,(n1+KeyData[0]) and $FF]);
  134. n1:= n1 xor (sTable[3,(n2+KeyData[1]) shr 24] xor sTable[2,((n2+KeyData[1]) shr 16) and $FF]
  135. xor sTable[1,((n2+KeyData[1]) shr 8) and $FF] xor sTable[0,(n2+KeyData[1]) and $FF]);
  136. n2:= n2 xor (sTable[3,(n1+KeyData[2]) shr 24] xor sTable[2,((n1+KeyData[2]) shr 16) and $FF]
  137. xor sTable[1,((n1+KeyData[2]) shr 8) and $FF] xor sTable[0,(n1+KeyData[2]) and $FF]);
  138. n1:= n1 xor (sTable[3,(n2+KeyData[3]) shr 24] xor sTable[2,((n2+KeyData[3]) shr 16) and $FF]
  139. xor sTable[1,((n2+KeyData[3]) shr 8) and $FF] xor sTable[0,(n2+KeyData[3]) and $FF]);
  140. n2:= n2 xor (sTable[3,(n1+KeyData[4]) shr 24] xor sTable[2,((n1+KeyData[4]) shr 16) and $FF]
  141. xor sTable[1,((n1+KeyData[4]) shr 8) and $FF] xor sTable[0,(n1+KeyData[4]) and $FF]);
  142. n1:= n1 xor (sTable[3,(n2+KeyData[5]) shr 24] xor sTable[2,((n2+KeyData[5]) shr 16) and $FF]
  143. xor sTable[1,((n2+KeyData[5]) shr 8) and $FF] xor sTable[0,(n2+KeyData[5]) and $FF]);
  144. n2:= n2 xor (sTable[3,(n1+KeyData[6]) shr 24] xor sTable[2,((n1+KeyData[6]) shr 16) and $FF]
  145. xor sTable[1,((n1+KeyData[6]) shr 8) and $FF] xor sTable[0,(n1+KeyData[6]) and $FF]);
  146. n1:= n1 xor (sTable[3,(n2+KeyData[7]) shr 24] xor sTable[2,((n2+KeyData[7]) shr 16) and $FF]
  147. xor sTable[1,((n2+KeyData[7]) shr 8) and $FF] xor sTable[0,(n2+KeyData[7]) and $FF]);
  148. end;
  149. n2:= n2 xor (sTable[3,(n1+KeyData[7]) shr 24] xor sTable[2,((n1+KeyData[7]) shr 16) and $FF]
  150. xor sTable[1,((n1+KeyData[7]) shr 8) and $FF] xor sTable[0,(n1+KeyData[7]) and $FF]);
  151. n1:= n1 xor (sTable[3,(n2+KeyData[6]) shr 24] xor sTable[2,((n2+KeyData[6]) shr 16) and $FF]
  152. xor sTable[1,((n2+KeyData[6]) shr 8) and $FF] xor sTable[0,(n2+KeyData[6]) and $FF]);
  153. n2:= n2 xor (sTable[3,(n1+KeyData[5]) shr 24] xor sTable[2,((n1+KeyData[5]) shr 16) and $FF]
  154. xor sTable[1,((n1+KeyData[5]) shr 8) and $FF] xor sTable[0,(n1+KeyData[5]) and $FF]);
  155. n1:= n1 xor (sTable[3,(n2+KeyData[4]) shr 24] xor sTable[2,((n2+KeyData[4]) shr 16) and $FF]
  156. xor sTable[1,((n2+KeyData[4]) shr 8) and $FF] xor sTable[0,(n2+KeyData[4]) and $FF]);
  157. n2:= n2 xor (sTable[3,(n1+KeyData[3]) shr 24] xor sTable[2,((n1+KeyData[3]) shr 16) and $FF]
  158. xor sTable[1,((n1+KeyData[3]) shr 8) and $FF] xor sTable[0,(n1+KeyData[3]) and $FF]);
  159. n1:= n1 xor (sTable[3,(n2+KeyData[2]) shr 24] xor sTable[2,((n2+KeyData[2]) shr 16) and $FF]
  160. xor sTable[1,((n2+KeyData[2]) shr 8) and $FF] xor sTable[0,(n2+KeyData[2]) and $FF]);
  161. n2:= n2 xor (sTable[3,(n1+KeyData[1]) shr 24] xor sTable[2,((n1+KeyData[1]) shr 16) and $FF]
  162. xor sTable[1,((n1+KeyData[1]) shr 8) and $FF] xor sTable[0,(n1+KeyData[1]) and $FF]);
  163. n1:= n1 xor (sTable[3,(n2+KeyData[0]) shr 24] xor sTable[2,((n2+KeyData[0]) shr 16) and $FF]
  164. xor sTable[1,((n2+KeyData[0]) shr 8) and $FF] xor sTable[0,(n2+KeyData[0]) and $FF]);
  165. PDword(@OutData)^:= n2;
  166. PDword(dword(@OutData)+4)^:= n1;
  167. end;
  168. procedure TDCP_gost.DecryptECB(const InData; var OutData);
  169. var
  170. n1, n2: DWord;
  171. i: longword;
  172. begin
  173. if not fInitialized then
  174. raise EDCP_blockcipher.Create('Cipher not initialized');
  175. n1:= PDword(@InData)^;
  176. n2:= PDword(dword(@InData)+4)^;
  177. n2:= n2 xor (sTable[3,(n1+KeyData[0]) shr 24] xor sTable[2,((n1+KeyData[0]) shr 16) and $FF]
  178. xor sTable[1,((n1+KeyData[0]) shr 8) and $FF] xor sTable[0,(n1+KeyData[0]) and $FF]);
  179. n1:= n1 xor (sTable[3,(n2+KeyData[1]) shr 24] xor sTable[2,((n2+KeyData[1]) shr 16) and $FF]
  180. xor sTable[1,((n2+KeyData[1]) shr 8) and $FF] xor sTable[0,(n2+KeyData[1]) and $FF]);
  181. n2:= n2 xor (sTable[3,(n1+KeyData[2]) shr 24] xor sTable[2,((n1+KeyData[2]) shr 16) and $FF]
  182. xor sTable[1,((n1+KeyData[2]) shr 8) and $FF] xor sTable[0,(n1+KeyData[2]) and $FF]);
  183. n1:= n1 xor (sTable[3,(n2+KeyData[3]) shr 24] xor sTable[2,((n2+KeyData[3]) shr 16) and $FF]
  184. xor sTable[1,((n2+KeyData[3]) shr 8) and $FF] xor sTable[0,(n2+KeyData[3]) and $FF]);
  185. n2:= n2 xor (sTable[3,(n1+KeyData[4]) shr 24] xor sTable[2,((n1+KeyData[4]) shr 16) and $FF]
  186. xor sTable[1,((n1+KeyData[4]) shr 8) and $FF] xor sTable[0,(n1+KeyData[4]) and $FF]);
  187. n1:= n1 xor (sTable[3,(n2+KeyData[5]) shr 24] xor sTable[2,((n2+KeyData[5]) shr 16) and $FF]
  188. xor sTable[1,((n2+KeyData[5]) shr 8) and $FF] xor sTable[0,(n2+KeyData[5]) and $FF]);
  189. n2:= n2 xor (sTable[3,(n1+KeyData[6]) shr 24] xor sTable[2,((n1+KeyData[6]) shr 16) and $FF]
  190. xor sTable[1,((n1+KeyData[6]) shr 8) and $FF] xor sTable[0,(n1+KeyData[6]) and $FF]);
  191. n1:= n1 xor (sTable[3,(n2+KeyData[7]) shr 24] xor sTable[2,((n2+KeyData[7]) shr 16) and $FF]
  192. xor sTable[1,((n2+KeyData[7]) shr 8) and $FF] xor sTable[0,(n2+KeyData[7]) and $FF]);
  193. for i:= 0 to 2 do
  194. begin
  195. n2:= n2 xor (sTable[3,(n1+KeyData[7]) shr 24] xor sTable[2,((n1+KeyData[7]) shr 16) and $FF]
  196. xor sTable[1,((n1+KeyData[7]) shr 8) and $FF] xor sTable[0,(n1+KeyData[7]) and $FF]);
  197. n1:= n1 xor (sTable[3,(n2+KeyData[6]) shr 24] xor sTable[2,((n2+KeyData[6]) shr 16) and $FF]
  198. xor sTable[1,((n2+KeyData[6]) shr 8) and $FF] xor sTable[0,(n2+KeyData[6]) and $FF]);
  199. n2:= n2 xor (sTable[3,(n1+KeyData[5]) shr 24] xor sTable[2,((n1+KeyData[5]) shr 16) and $FF]
  200. xor sTable[1,((n1+KeyData[5]) shr 8) and $FF] xor sTable[0,(n1+KeyData[5]) and $FF]);
  201. n1:= n1 xor (sTable[3,(n2+KeyData[4]) shr 24] xor sTable[2,((n2+KeyData[4]) shr 16) and $FF]
  202. xor sTable[1,((n2+KeyData[4]) shr 8) and $FF] xor sTable[0,(n2+KeyData[4]) and $FF]);
  203. n2:= n2 xor (sTable[3,(n1+KeyData[3]) shr 24] xor sTable[2,((n1+KeyData[3]) shr 16) and $FF]
  204. xor sTable[1,((n1+KeyData[3]) shr 8) and $FF] xor sTable[0,(n1+KeyData[3]) and $FF]);
  205. n1:= n1 xor (sTable[3,(n2+KeyData[2]) shr 24] xor sTable[2,((n2+KeyData[2]) shr 16) and $FF]
  206. xor sTable[1,((n2+KeyData[2]) shr 8) and $FF] xor sTable[0,(n2+KeyData[2]) and $FF]);
  207. n2:= n2 xor (sTable[3,(n1+KeyData[1]) shr 24] xor sTable[2,((n1+KeyData[1]) shr 16) and $FF]
  208. xor sTable[1,((n1+KeyData[1]) shr 8) and $FF] xor sTable[0,(n1+KeyData[1]) and $FF]);
  209. n1:= n1 xor (sTable[3,(n2+KeyData[0]) shr 24] xor sTable[2,((n2+KeyData[0]) shr 16) and $FF]
  210. xor sTable[1,((n2+KeyData[0]) shr 8) and $FF] xor sTable[0,(n2+KeyData[0]) and $FF]);
  211. end;
  212. PDword(@OutData)^:= n2;
  213. PDword(dword(@OutData)+4)^:= n1;
  214. end;
  215. end.