dcpcrypt2.pas 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton ([email protected]) **********}
  3. {******************************************************************************}
  4. {* Main component definitions *************************************************}
  5. {******************************************************************************}
  6. {* Copyright (C) 1999-2003 David Barton *}
  7. {* Copyright (C) 2018 Alexander Koblov ([email protected]) *}
  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. unit DCPcrypt2;
  27. {$MODE Delphi}
  28. interface
  29. uses
  30. Classes, Sysutils, DCPbase64;
  31. //{$DEFINE DCP1COMPAT} { DCPcrypt v1.31 compatiblity mode - see documentation }
  32. {******************************************************************************}
  33. { A few predefined types to help out }
  34. type
  35. {$IFNDEF FPC}
  36. Pbyte= ^byte;
  37. Pword= ^word;
  38. Pdword= ^dword;
  39. Pint64= ^int64;
  40. dword= longword;
  41. Pwordarray= ^Twordarray;
  42. Twordarray= array[0..19383] of word;
  43. {$ENDIF}
  44. Pdwordarray= ^Tdwordarray;
  45. Tdwordarray= array[0..8191] of dword;
  46. {******************************************************************************}
  47. { The base class from which all hash algorithms are to be derived }
  48. type
  49. EDCP_hash= class(Exception);
  50. TDCP_hash= class(TComponent)
  51. protected
  52. fInitialized: boolean; { Whether or not the algorithm has been initialized }
  53. procedure DeadInt(Value: integer); { Knudge to display vars in the object inspector }
  54. procedure DeadStr(Value: string); { Knudge to display vars in the object inspector }
  55. private
  56. function _GetId: integer;
  57. function _GetAlgorithm: string;
  58. function _GetHashSize: integer;
  59. public
  60. property Initialized: boolean
  61. read fInitialized;
  62. class function GetId: integer; virtual;
  63. { Get the algorithm id }
  64. class function GetAlgorithm: string; virtual;
  65. { Get the algorithm name }
  66. class function GetHashSize: integer; virtual;
  67. { Get the size of the digest produced - in bits }
  68. class function SelfTest: boolean; virtual;
  69. { Tests the implementation with several test vectors }
  70. procedure Init; virtual;
  71. { Initialize the hash algorithm }
  72. procedure Final(var Digest); virtual;
  73. { Create the final digest and clear the stored information.
  74. The size of the Digest var must be at least equal to the hash size }
  75. procedure Burn; virtual;
  76. { Clear any stored information with out creating the final digest }
  77. procedure Update(const Buffer; Size: longword); virtual;
  78. { Update the hash buffer with Size bytes of data from Buffer }
  79. procedure UpdateStream(Stream: TStream; Size: QWord);
  80. { Update the hash buffer with Size bytes of data from the stream }
  81. procedure UpdateStr(const Str: string);
  82. { Update the hash buffer with the string }
  83. destructor Destroy; override;
  84. published
  85. property Id: integer
  86. read _GetId write DeadInt;
  87. property Algorithm: string
  88. read _GetAlgorithm write DeadStr;
  89. property HashSize: integer
  90. read _GetHashSize write DeadInt;
  91. end;
  92. TDCP_hashclass= class of TDCP_hash;
  93. {******************************************************************************}
  94. { The base class from which all encryption components will be derived. }
  95. { Stream ciphers will be derived directly from this class where as }
  96. { Block ciphers will have a further foundation class TDCP_blockcipher. }
  97. type
  98. EDCP_cipher= class(Exception);
  99. TDCP_cipher= class(TComponent)
  100. protected
  101. fInitialized: boolean; { Whether or not the key setup has been done yet }
  102. procedure DeadInt(Value: integer); { Knudge to display vars in the object inspector }
  103. procedure DeadStr(Value: string); { Knudge to display vars in the object inspector }
  104. private
  105. function _GetId: integer;
  106. function _GetAlgorithm: string;
  107. function _GetMaxKeySize: integer;
  108. public
  109. property Initialized: boolean
  110. read fInitialized;
  111. class function GetId: integer; virtual;
  112. { Get the algorithm id }
  113. class function GetAlgorithm: string; virtual;
  114. { Get the algorithm name }
  115. class function GetMaxKeySize: integer; virtual;
  116. { Get the maximum key size (in bits) }
  117. class function SelfTest: boolean; virtual;
  118. { Tests the implementation with several test vectors }
  119. procedure Init(const Key; Size: longword; InitVector: pointer); virtual;
  120. { Do key setup based on the data in Key, size is in bits }
  121. procedure InitStr(const Key: string; HashType: TDCP_hashclass);
  122. { Do key setup based on a hash of the key string }
  123. procedure Burn; virtual;
  124. { Clear all stored key information }
  125. procedure Reset; virtual;
  126. { Reset any stored chaining information }
  127. procedure Encrypt(const Indata; var Outdata; Size: longword); virtual;
  128. { Encrypt size bytes of data and place in Outdata }
  129. procedure Decrypt(const Indata; var Outdata; Size: longword); virtual;
  130. { Decrypt size bytes of data and place in Outdata }
  131. function EncryptStream(InStream, OutStream: TStream; Size: longword): longword;
  132. { Encrypt size bytes of data from InStream and place in OutStream }
  133. function DecryptStream(InStream, OutStream: TStream; Size: longword): longword;
  134. { Decrypt size bytes of data from InStream and place in OutStream }
  135. function EncryptString(const Str: string): string; virtual;
  136. { Encrypt a string and return Base64 encoded }
  137. function DecryptString(const Str: string): string; virtual;
  138. { Decrypt a Base64 encoded string }
  139. constructor Create(AOwner: TComponent); override;
  140. destructor Destroy; override;
  141. published
  142. property Id: integer
  143. read _GetId write DeadInt;
  144. property Algorithm: string
  145. read _GetAlgorithm write DeadStr;
  146. property MaxKeySize: integer
  147. read _GetMaxKeySize write DeadInt;
  148. end;
  149. TDCP_cipherclass= class of TDCP_cipher;
  150. {******************************************************************************}
  151. { The base class from which all block ciphers are to be derived, this }
  152. { extra class takes care of the different block encryption modes. }
  153. type
  154. TDCP_ciphermode= (cmCBC, cmCFB8bit, cmCFBblock, cmOFB, cmCTR); // cmCFB8bit is equal to DCPcrypt v1.xx's CFB mode
  155. EDCP_blockcipher= class(EDCP_cipher);
  156. TDCP_blockcipher= class(TDCP_cipher)
  157. protected
  158. fCipherMode: TDCP_ciphermode; { The cipher mode the encrypt method uses }
  159. procedure InitKey(const Key; Size: longword); virtual;
  160. private
  161. function _GetBlockSize: integer;
  162. public
  163. class function GetBlockSize: integer; virtual;
  164. { Get the block size of the cipher (in bits) }
  165. procedure SetIV(const Value); virtual;
  166. { Sets the IV to Value and performs a reset }
  167. procedure GetIV(var Value); virtual;
  168. { Returns the current chaining information, not the actual IV }
  169. procedure Encrypt(const Indata; var Outdata; Size: longword); override;
  170. { Encrypt size bytes of data and place in Outdata using CipherMode }
  171. procedure Decrypt(const Indata; var Outdata; Size: longword); override;
  172. { Decrypt size bytes of data and place in Outdata using CipherMode }
  173. function EncryptString(const Str: string): string; override;
  174. { Encrypt a string and return Base64 encoded }
  175. function DecryptString(const Str: string): string; override;
  176. { Decrypt a Base64 encoded string }
  177. procedure EncryptECB(const Indata; var Outdata); virtual;
  178. { Encrypt a block of data using the ECB method of encryption }
  179. procedure DecryptECB(const Indata; var Outdata); virtual;
  180. { Decrypt a block of data using the ECB method of decryption }
  181. procedure EncryptCBC(const Indata; var Outdata; Size: longword); virtual;
  182. { Encrypt size bytes of data using the CBC method of encryption }
  183. procedure DecryptCBC(const Indata; var Outdata; Size: longword); virtual;
  184. { Decrypt size bytes of data using the CBC method of decryption }
  185. procedure EncryptCFB8bit(const Indata; var Outdata; Size: longword); virtual;
  186. { Encrypt size bytes of data using the CFB (8 bit) method of encryption }
  187. procedure DecryptCFB8bit(const Indata; var Outdata; Size: longword); virtual;
  188. { Decrypt size bytes of data using the CFB (8 bit) method of decryption }
  189. procedure EncryptCFBblock(const Indata; var Outdata; Size: longword); virtual;
  190. { Encrypt size bytes of data using the CFB (block) method of encryption }
  191. procedure DecryptCFBblock(const Indata; var Outdata; Size: longword); virtual;
  192. { Decrypt size bytes of data using the CFB (block) method of decryption }
  193. procedure EncryptOFB(const Indata; var Outdata; Size: longword); virtual;
  194. { Encrypt size bytes of data using the OFB method of encryption }
  195. procedure DecryptOFB(const Indata; var Outdata; Size: longword); virtual;
  196. { Decrypt size bytes of data using the OFB method of decryption }
  197. procedure EncryptCTR(const Indata; var Outdata; Size: longword); virtual;
  198. { Encrypt size bytes of data using the CTR method of encryption }
  199. procedure DecryptCTR(const Indata; var Outdata; Size: longword); virtual;
  200. { Decrypt size bytes of data using the CTR method of decryption }
  201. constructor Create(AOwner: TComponent); override;
  202. published
  203. property BlockSize: integer
  204. read _GetBlockSize write DeadInt;
  205. property CipherMode: TDCP_ciphermode
  206. read fCipherMode write fCipherMode default cmCBC;
  207. end;
  208. TDCP_blockcipherclass= class of TDCP_blockcipher;
  209. {******************************************************************************}
  210. { Helper functions }
  211. procedure XorBlock(var InData1, InData2; Size: longword);
  212. // Supposed to be an optimized version of XorBlock() using 32-bit xor
  213. procedure XorBlockEx(var InData1, InData2; Size: longword);
  214. // removes the compiler hint due to first param being 'var' instead of 'out'
  215. procedure dcpFillChar(out x; count: SizeInt; Value: Byte); overload;
  216. procedure dcpFillChar(out x; count: SizeInt; Value: Char); overload;
  217. procedure ZeroMemory(Destination: Pointer; Length: PtrUInt);
  218. {$IF DEFINED(CPUX86_64)}
  219. function BMI2Support: LongBool;
  220. function SSSE3Support: LongBool;
  221. {$ENDIF}
  222. implementation
  223. {$Q-}{$R-}
  224. {** TDCP_hash *****************************************************************}
  225. procedure TDCP_hash.DeadInt(Value: integer);
  226. begin
  227. end;
  228. procedure TDCP_hash.DeadStr(Value: string);
  229. begin
  230. end;
  231. function TDCP_hash._GetId: integer;
  232. begin
  233. Result:= GetId;
  234. end;
  235. function TDCP_hash._GetAlgorithm: string;
  236. begin
  237. Result:= GetAlgorithm;
  238. end;
  239. function TDCP_hash._GetHashSize: integer;
  240. begin
  241. Result:= GetHashSize;
  242. end;
  243. class function TDCP_hash.GetId: integer;
  244. begin
  245. Result:= -1;
  246. end;
  247. class function TDCP_hash.GetAlgorithm: string;
  248. begin
  249. Result:= '';
  250. end;
  251. class function TDCP_hash.GetHashSize: integer;
  252. begin
  253. Result:= -1;
  254. end;
  255. class function TDCP_hash.SelfTest: boolean;
  256. begin
  257. Result:= false;
  258. end;
  259. procedure TDCP_hash.Init;
  260. begin
  261. end;
  262. procedure TDCP_hash.Final(var Digest);
  263. begin
  264. end;
  265. procedure TDCP_hash.Burn;
  266. begin
  267. end;
  268. procedure TDCP_hash.Update(const Buffer; Size: longword);
  269. begin
  270. end;
  271. procedure TDCP_hash.UpdateStream(Stream: TStream; Size: QWord);
  272. var
  273. Buffer: array[0..8191] of byte;
  274. i, read: integer;
  275. begin
  276. dcpFillChar(Buffer, SizeOf(Buffer), 0);
  277. for i:= 1 to (Size div Sizeof(Buffer)) do
  278. begin
  279. read:= Stream.Read(Buffer,Sizeof(Buffer));
  280. Update(Buffer,read);
  281. end;
  282. if (Size mod Sizeof(Buffer))<> 0 then
  283. begin
  284. read:= Stream.Read(Buffer,Size mod Sizeof(Buffer));
  285. Update(Buffer,read);
  286. end;
  287. end;
  288. procedure TDCP_hash.UpdateStr(const Str: string);
  289. begin
  290. Update(Str[1],Length(Str));
  291. end;
  292. destructor TDCP_hash.Destroy;
  293. begin
  294. if fInitialized then
  295. Burn;
  296. inherited Destroy;
  297. end;
  298. {** TDCP_cipher ***************************************************************}
  299. procedure TDCP_cipher.DeadInt(Value: integer);
  300. begin
  301. end;
  302. procedure TDCP_cipher.DeadStr(Value: string);
  303. begin
  304. end;
  305. function TDCP_cipher._GetId: integer;
  306. begin
  307. Result:= GetId;
  308. end;
  309. function TDCP_cipher._GetAlgorithm: string;
  310. begin
  311. Result:= GetAlgorithm;
  312. end;
  313. function TDCP_cipher._GetMaxKeySize: integer;
  314. begin
  315. Result:= GetMaxKeySize;
  316. end;
  317. class function TDCP_cipher.GetId: integer;
  318. begin
  319. Result:= -1;
  320. end;
  321. class function TDCP_cipher.GetAlgorithm: string;
  322. begin
  323. Result:= '';
  324. end;
  325. class function TDCP_cipher.GetMaxKeySize: integer;
  326. begin
  327. Result:= -1;
  328. end;
  329. class function TDCP_cipher.SelfTest: boolean;
  330. begin
  331. Result:= false;
  332. end;
  333. procedure TDCP_cipher.Init(const Key; Size: longword; InitVector: pointer);
  334. begin
  335. if fInitialized then
  336. Burn;
  337. if (Size <= 0) or ((Size and 3)<> 0) or (Size> longword(GetMaxKeySize)) then
  338. raise EDCP_cipher.Create('Invalid key size')
  339. else
  340. fInitialized:= true;
  341. end;
  342. procedure TDCP_cipher.InitStr(const Key: string; HashType: TDCP_hashclass);
  343. var
  344. Hash: TDCP_hash;
  345. Digest: pointer;
  346. begin
  347. if fInitialized then
  348. Burn;
  349. try
  350. GetMem(Digest,HashType.GetHashSize div 8);
  351. Hash:= HashType.Create(Self);
  352. Hash.Init;
  353. Hash.UpdateStr(Key);
  354. Hash.Final(Digest^);
  355. Hash.Free;
  356. if MaxKeySize< HashType.GetHashSize then
  357. begin
  358. Init(Digest^,MaxKeySize,nil);
  359. end
  360. else
  361. begin
  362. Init(Digest^,HashType.GetHashSize,nil);
  363. end;
  364. FillChar(Digest^,HashType.GetHashSize div 8,$FF);
  365. FreeMem(Digest);
  366. except
  367. raise EDCP_cipher.Create('Unable to allocate sufficient memory for hash digest');
  368. end;
  369. end;
  370. procedure TDCP_cipher.Burn;
  371. begin
  372. fInitialized:= false;
  373. end;
  374. procedure TDCP_cipher.Reset;
  375. begin
  376. end;
  377. procedure TDCP_cipher.Encrypt(const Indata; var Outdata; Size: longword);
  378. begin
  379. end;
  380. procedure TDCP_cipher.Decrypt(const Indata; var Outdata; Size: longword);
  381. begin
  382. end;
  383. function TDCP_cipher.EncryptStream(InStream, OutStream: TStream; Size: longword): longword;
  384. var
  385. Buffer: array[0..8191] of byte;
  386. i, Read: longword;
  387. begin
  388. dcpFillChar(Buffer, SizeOf(Buffer), 0);
  389. Result:= 0;
  390. for i:= 1 to (Size div Sizeof(Buffer)) do
  391. begin
  392. Read:= InStream.Read(Buffer,Sizeof(Buffer));
  393. Inc(Result,Read);
  394. Encrypt(Buffer,Buffer,Read);
  395. OutStream.Write(Buffer,Read);
  396. end;
  397. if (Size mod Sizeof(Buffer))<> 0 then
  398. begin
  399. Read:= InStream.Read(Buffer,Size mod Sizeof(Buffer));
  400. Inc(Result,Read);
  401. Encrypt(Buffer,Buffer,Read);
  402. OutStream.Write(Buffer,Read);
  403. end;
  404. end;
  405. function TDCP_cipher.DecryptStream(InStream, OutStream: TStream; Size: longword): longword;
  406. var
  407. Buffer: array[0..8191] of byte;
  408. i, Read: longword;
  409. begin
  410. dcpFillChar(Buffer, SizeOf(Buffer), 0);
  411. Result:= 0;
  412. for i:= 1 to (Size div Sizeof(Buffer)) do
  413. begin
  414. Read:= InStream.Read(Buffer,Sizeof(Buffer));
  415. Inc(Result,Read);
  416. Decrypt(Buffer,Buffer,Read);
  417. OutStream.Write(Buffer,Read);
  418. end;
  419. if (Size mod Sizeof(Buffer))<> 0 then
  420. begin
  421. Read:= InStream.Read(Buffer,Size mod Sizeof(Buffer));
  422. Inc(Result,Read);
  423. Decrypt(Buffer,Buffer,Read);
  424. OutStream.Write(Buffer,Read);
  425. end;
  426. end;
  427. function TDCP_cipher.EncryptString(const Str: string): string;
  428. begin
  429. SetLength(Result,Length(Str));
  430. Encrypt(Str[1],Result[1],Length(Str));
  431. Result:= Base64EncodeStr(Result);
  432. end;
  433. function TDCP_cipher.DecryptString(const Str: string): string;
  434. begin
  435. Result:= Base64DecodeStr(Str);
  436. Decrypt(Result[1],Result[1],Length(Result));
  437. end;
  438. constructor TDCP_cipher.Create(AOwner: TComponent);
  439. begin
  440. inherited Create(AOwner);
  441. Burn;
  442. end;
  443. destructor TDCP_cipher.Destroy;
  444. begin
  445. if fInitialized then
  446. Burn;
  447. inherited Destroy;
  448. end;
  449. {** TDCP_blockcipher **********************************************************}
  450. procedure TDCP_blockcipher.InitKey(const Key; Size: longword);
  451. begin
  452. end;
  453. function TDCP_blockcipher._GetBlockSize: integer;
  454. begin
  455. Result:= GetBlockSize;
  456. end;
  457. class function TDCP_blockcipher.GetBlockSize: integer;
  458. begin
  459. Result:= -1;
  460. end;
  461. procedure TDCP_blockcipher.SetIV(const Value);
  462. begin
  463. end;
  464. procedure TDCP_blockcipher.GetIV(var Value);
  465. begin
  466. end;
  467. procedure TDCP_blockcipher.Encrypt(const Indata; var Outdata; Size: longword);
  468. begin
  469. case fCipherMode of
  470. cmCBC: EncryptCBC(Indata,Outdata,Size);
  471. cmCFB8bit: EncryptCFB8bit(Indata,Outdata,Size);
  472. cmCFBblock: EncryptCFBblock(Indata,Outdata,Size);
  473. cmOFB: EncryptOFB(Indata,Outdata,Size);
  474. cmCTR: EncryptCTR(Indata,Outdata,Size);
  475. end;
  476. end;
  477. function TDCP_blockcipher.EncryptString(const Str: string): string;
  478. begin
  479. SetLength(Result,Length(Str));
  480. EncryptCFB8bit(Str[1],Result[1],Length(Str));
  481. Result:= Base64EncodeStr(Result);
  482. end;
  483. function TDCP_blockcipher.DecryptString(const Str: string): string;
  484. begin
  485. Result:= Base64DecodeStr(Str);
  486. DecryptCFB8bit(Result[1],Result[1],Length(Result));
  487. end;
  488. procedure TDCP_blockcipher.Decrypt(const Indata; var Outdata; Size: longword);
  489. begin
  490. case fCipherMode of
  491. cmCBC: DecryptCBC(Indata,Outdata,Size);
  492. cmCFB8bit: DecryptCFB8bit(Indata,Outdata,Size);
  493. cmCFBblock: DecryptCFBblock(Indata,Outdata,Size);
  494. cmOFB: DecryptOFB(Indata,Outdata,Size);
  495. cmCTR: DecryptCTR(Indata,Outdata,Size);
  496. end;
  497. end;
  498. procedure TDCP_blockcipher.EncryptECB(const Indata; var Outdata);
  499. begin
  500. end;
  501. procedure TDCP_blockcipher.DecryptECB(const Indata; var Outdata);
  502. begin
  503. end;
  504. procedure TDCP_blockcipher.EncryptCBC(const Indata; var Outdata; Size: longword);
  505. begin
  506. end;
  507. procedure TDCP_blockcipher.DecryptCBC(const Indata; var Outdata; Size: longword);
  508. begin
  509. end;
  510. procedure TDCP_blockcipher.EncryptCFB8bit(const Indata; var Outdata; Size: longword);
  511. begin
  512. end;
  513. procedure TDCP_blockcipher.DecryptCFB8bit(const Indata; var Outdata; Size: longword);
  514. begin
  515. end;
  516. procedure TDCP_blockcipher.EncryptCFBblock(const Indata; var Outdata; Size: longword);
  517. begin
  518. end;
  519. procedure TDCP_blockcipher.DecryptCFBblock(const Indata; var Outdata; Size: longword);
  520. begin
  521. end;
  522. procedure TDCP_blockcipher.EncryptOFB(const Indata; var Outdata; Size: longword);
  523. begin
  524. end;
  525. procedure TDCP_blockcipher.DecryptOFB(const Indata; var Outdata; Size: longword);
  526. begin
  527. end;
  528. procedure TDCP_blockcipher.EncryptCTR(const Indata; var Outdata; Size: longword);
  529. begin
  530. end;
  531. procedure TDCP_blockcipher.DecryptCTR(const Indata; var Outdata; Size: longword);
  532. begin
  533. end;
  534. constructor TDCP_blockcipher.Create(AOwner: TComponent);
  535. begin
  536. inherited Create(AOwner);
  537. fCipherMode:= cmCBC;
  538. end;
  539. {** Helpher functions *********************************************************}
  540. procedure XorBlock(var InData1, InData2; Size: longword);
  541. var
  542. b1: PByteArray;
  543. b2: PByteArray;
  544. i: longword;
  545. begin
  546. b1 := @InData1;
  547. b2 := @InData2;
  548. for i := 0 to size-1 do
  549. b1[i] := b1[i] xor b2[i];
  550. end;
  551. procedure dcpFillChar(out x; count: SizeInt; Value: Byte);
  552. begin
  553. {$HINTS OFF}
  554. FillChar(x, count, value);
  555. {$HINTS ON}
  556. end;
  557. procedure ZeroMemory(Destination: Pointer; Length: PtrUInt);
  558. begin
  559. FillChar(Destination^, Length, 0);
  560. end;
  561. procedure dcpFillChar(out x; count: SizeInt; Value: Char);
  562. begin
  563. {$HINTS OFF}
  564. FillChar(x, count, Value);
  565. {$HINTS ON}
  566. end;
  567. // Supposed to be an optimized version of XorBlock() using 32-bit xor
  568. procedure XorBlockEx(var InData1, InData2; Size: longword);
  569. var
  570. l1: PIntegerArray;
  571. l2: PIntegerArray;
  572. b1: PByteArray;
  573. b2: PByteArray;
  574. i: integer;
  575. c: integer;
  576. begin
  577. l1 := @inData1;
  578. l2 := @inData2;
  579. for i := 0 to size div sizeof(LongWord)-1 do
  580. l1[i] := l1[i] xor l2[i];
  581. // the rest of the buffer (3 bytes)
  582. c := size mod sizeof(longWord);
  583. if c > 0 then begin
  584. b1 := @InData1;
  585. b2 := @InData2;
  586. for i := (size-c) to size-1 do
  587. b1[i] := b1[i] xor b2[i];
  588. end;
  589. end;
  590. {$IF DEFINED(CPUX86_64)}
  591. function BMI2Support: LongBool; assembler; nostackframe;
  592. asm
  593. pushq %rbx
  594. movl $7,%eax
  595. movl $0,%ecx
  596. cpuid
  597. andl $256,%ebx
  598. movl %ebx,%eax
  599. popq %rbx
  600. end;
  601. function SSSE3Support: LongBool; assembler; nostackframe;
  602. asm
  603. pushq %rbx
  604. movl $1,%eax
  605. cpuid
  606. andl $512,%ecx
  607. movl %ecx,%eax
  608. popq %rbx
  609. end;
  610. {$ENDIF}
  611. end.