DCPblockciphers.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* Block cipher 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 DCPblockciphers;
  26. interface
  27. uses
  28. Classes, Sysutils, DCPcrypt2;
  29. {******************************************************************************}
  30. { Base type definition for 64 bit block ciphers }
  31. type
  32. TDCP_blockcipher64= class(TDCP_blockcipher)
  33. private
  34. IV, CV: array[0..7] of byte;
  35. procedure IncCounter;
  36. public
  37. class function GetBlockSize: integer; override;
  38. { Get the block size of the cipher (in bits) }
  39. procedure Reset; override;
  40. { Reset any stored chaining information }
  41. procedure Burn; override;
  42. { Clear all stored key information and chaining information }
  43. procedure SetIV(const Value); override;
  44. { Sets the IV to Value and performs a reset }
  45. procedure GetIV(var Value); override;
  46. { Returns the current chaining information, not the actual IV }
  47. procedure Init(const Key; Size: longword; InitVector: pointer); override;
  48. { Do key setup based on the data in Key, size is in bits }
  49. procedure EncryptCBC(const Indata; var Outdata; Size: longword); override;
  50. { Encrypt size bytes of data using the CBC method of encryption }
  51. procedure DecryptCBC(const Indata; var Outdata; Size: longword); override;
  52. { Decrypt size bytes of data using the CBC method of decryption }
  53. procedure EncryptCFB8bit(const Indata; var Outdata; Size: longword); override;
  54. { Encrypt size bytes of data using the CFB (8 bit) method of encryption }
  55. procedure DecryptCFB8bit(const Indata; var Outdata; Size: longword); override;
  56. { Decrypt size bytes of data using the CFB (8 bit) method of decryption }
  57. procedure EncryptCFBblock(const Indata; var Outdata; Size: longword); override;
  58. { Encrypt size bytes of data using the CFB (block) method of encryption }
  59. procedure DecryptCFBblock(const Indata; var Outdata; Size: longword); override;
  60. { Decrypt size bytes of data using the CFB (block) method of decryption }
  61. procedure EncryptOFB(const Indata; var Outdata; Size: longword); override;
  62. { Encrypt size bytes of data using the OFB method of encryption }
  63. procedure DecryptOFB(const Indata; var Outdata; Size: longword); override;
  64. { Decrypt size bytes of data using the OFB method of decryption }
  65. procedure EncryptCTR(const Indata; var Outdata; Size: longword); override;
  66. { Encrypt size bytes of data using the CTR method of encryption }
  67. procedure DecryptCTR(const Indata; var Outdata; Size: longword); override;
  68. { Decrypt size bytes of data using the CTR method of decryption }
  69. end;
  70. {******************************************************************************}
  71. { Base type definition for 128 bit block ciphers }
  72. type
  73. TDCP_blockcipher128= class(TDCP_blockcipher)
  74. private
  75. IV, CV: array[0..15] of byte;
  76. procedure IncCounter;
  77. public
  78. class function GetBlockSize: integer; override;
  79. { Get the block size of the cipher (in bits) }
  80. procedure Reset; override;
  81. { Reset any stored chaining information }
  82. procedure Burn; override;
  83. { Clear all stored key information and chaining information }
  84. procedure SetIV(const Value); override;
  85. { Sets the IV to Value and performs a reset }
  86. procedure GetIV(var Value); override;
  87. { Returns the current chaining information, not the actual IV }
  88. procedure Init(const Key; Size: longword; InitVector: pointer); override;
  89. { Do key setup based on the data in Key, size is in bits }
  90. procedure EncryptCBC(const Indata; var Outdata; Size: longword); override;
  91. { Encrypt size bytes of data using the CBC method of encryption }
  92. procedure DecryptCBC(const Indata; var Outdata; Size: longword); override;
  93. { Decrypt size bytes of data using the CBC method of decryption }
  94. procedure EncryptCFB8bit(const Indata; var Outdata; Size: longword); override;
  95. { Encrypt size bytes of data using the CFB (8 bit) method of encryption }
  96. procedure DecryptCFB8bit(const Indata; var Outdata; Size: longword); override;
  97. { Decrypt size bytes of data using the CFB (8 bit) method of decryption }
  98. procedure EncryptCFBblock(const Indata; var Outdata; Size: longword); override;
  99. { Encrypt size bytes of data using the CFB (block) method of encryption }
  100. procedure DecryptCFBblock(const Indata; var Outdata; Size: longword); override;
  101. { Decrypt size bytes of data using the CFB (block) method of decryption }
  102. procedure EncryptOFB(const Indata; var Outdata; Size: longword); override;
  103. { Encrypt size bytes of data using the OFB method of encryption }
  104. procedure DecryptOFB(const Indata; var Outdata; Size: longword); override;
  105. { Decrypt size bytes of data using the OFB method of decryption }
  106. procedure EncryptCTR(const Indata; var Outdata; Size: longword); override;
  107. { Encrypt size bytes of data using the CTR method of encryption }
  108. procedure DecryptCTR(const Indata; var Outdata; Size: longword); override;
  109. { Decrypt size bytes of data using the CTR method of decryption }
  110. end;
  111. implementation
  112. {** TDCP_blockcipher64 ********************************************************}
  113. procedure TDCP_blockcipher64.IncCounter;
  114. var
  115. i: integer;
  116. begin
  117. Inc(CV[7]);
  118. i:= 7;
  119. while (i> 0) and (CV[i] = 0) do
  120. begin
  121. Inc(CV[i-1]);
  122. Dec(i);
  123. end;
  124. end;
  125. class function TDCP_blockcipher64.GetBlockSize: integer;
  126. begin
  127. Result:= 64;
  128. end;
  129. procedure TDCP_blockcipher64.Init(const Key; Size: longword; InitVector: pointer);
  130. begin
  131. inherited Init(Key,Size,InitVector);
  132. InitKey(Key,Size);
  133. if InitVector= nil then
  134. begin
  135. FillChar(IV,8,{$IFDEF DCP1COMPAT}$FF{$ELSE}0{$ENDIF});
  136. EncryptECB(IV,IV);
  137. Reset;
  138. end
  139. else
  140. begin
  141. Move(InitVector^,IV,8);
  142. Reset;
  143. end;
  144. end;
  145. procedure TDCP_blockcipher64.SetIV(const Value);
  146. begin
  147. if not fInitialized then
  148. raise EDCP_blockcipher.Create('Cipher not initialized');
  149. Move(Value,IV,8);
  150. Reset;
  151. end;
  152. procedure TDCP_blockcipher64.GetIV(var Value);
  153. begin
  154. if not fInitialized then
  155. raise EDCP_blockcipher.Create('Cipher not initialized');
  156. Move(CV,Value,8);
  157. end;
  158. procedure TDCP_blockcipher64.Reset;
  159. begin
  160. if not fInitialized then
  161. raise EDCP_blockcipher.Create('Cipher not initialized')
  162. else
  163. Move(IV,CV,8);
  164. end;
  165. procedure TDCP_blockcipher64.Burn;
  166. begin
  167. FillChar(IV,8,$FF);
  168. FillChar(CV,8,$FF);
  169. inherited Burn;
  170. end;
  171. procedure TDCP_blockcipher64.EncryptCBC(const Indata; var Outdata; Size: longword);
  172. var
  173. i: longword;
  174. p1, p2: pointer;
  175. begin
  176. if not fInitialized then
  177. raise EDCP_blockcipher.Create('Cipher not initialized');
  178. p1:= @Indata;
  179. p2:= @Outdata;
  180. for i:= 1 to (Size div 8) do
  181. begin
  182. Move(p1^,p2^,8);
  183. XorBlock(p2^,CV,8);
  184. EncryptECB(p2^,p2^);
  185. Move(p2^,CV,8);
  186. p1:= pointer(longword(p1) + 8);
  187. p2:= pointer(longword(p2) + 8);
  188. end;
  189. if (Size mod 8)<> 0 then
  190. begin
  191. EncryptECB(CV,CV);
  192. Move(p1^,p2^,Size mod 8);
  193. XorBlock(p2^,CV,Size mod 8);
  194. end;
  195. end;
  196. procedure TDCP_blockcipher64.DecryptCBC(const Indata; var Outdata; Size: longword);
  197. var
  198. i: longword;
  199. p1, p2: pointer;
  200. Temp: array[0..7] of byte;
  201. begin
  202. if not fInitialized then
  203. raise EDCP_blockcipher.Create('Cipher not initialized');
  204. p1:= @Indata;
  205. p2:= @Outdata;
  206. for i:= 1 to (Size div 8) do
  207. begin
  208. Move(p1^,p2^,8);
  209. Move(p1^,Temp,8);
  210. DecryptECB(p2^,p2^);
  211. XorBlock(p2^,CV,8);
  212. Move(Temp,CV,8);
  213. p1:= pointer(longword(p1) + 8);
  214. p2:= pointer(longword(p2) + 8);
  215. end;
  216. if (Size mod 8)<> 0 then
  217. begin
  218. EncryptECB(CV,CV);
  219. Move(p1^,p2^,Size mod 8);
  220. XorBlock(p2^,CV,Size mod 8);
  221. end;
  222. end;
  223. procedure TDCP_blockcipher64.EncryptCFB8bit(const Indata; var Outdata; Size: longword);
  224. var
  225. i: longword;
  226. p1, p2: Pbyte;
  227. Temp: array[0..7] of byte;
  228. begin
  229. if not fInitialized then
  230. raise EDCP_blockcipher.Create('Cipher not initialized');
  231. p1:= @Indata;
  232. p2:= @Outdata;
  233. for i:= 1 to Size do
  234. begin
  235. EncryptECB(CV,Temp);
  236. p2^:= p1^ xor Temp[0];
  237. Move(CV[1],CV[0],8-1);
  238. CV[7]:= p2^;
  239. Inc(p1);
  240. Inc(p2);
  241. end;
  242. end;
  243. procedure TDCP_blockcipher64.DecryptCFB8bit(const Indata; var Outdata; Size: longword);
  244. var
  245. i: longword;
  246. p1, p2: Pbyte;
  247. TempByte: byte;
  248. Temp: array[0..7] of byte;
  249. begin
  250. if not fInitialized then
  251. raise EDCP_blockcipher.Create('Cipher not initialized');
  252. p1:= @Indata;
  253. p2:= @Outdata;
  254. for i:= 1 to Size do
  255. begin
  256. TempByte:= p1^;
  257. EncryptECB(CV,Temp);
  258. p2^:= p1^ xor Temp[0];
  259. Move(CV[1],CV[0],8-1);
  260. CV[7]:= TempByte;
  261. Inc(p1);
  262. Inc(p2);
  263. end;
  264. end;
  265. procedure TDCP_blockcipher64.EncryptCFBblock(const Indata; var Outdata; Size: longword);
  266. var
  267. i: longword;
  268. p1, p2: Pbyte;
  269. begin
  270. if not fInitialized then
  271. raise EDCP_blockcipher.Create('Cipher not initialized');
  272. p1:= @Indata;
  273. p2:= @Outdata;
  274. for i:= 1 to (Size div 8) do
  275. begin
  276. EncryptECB(CV,CV);
  277. Move(p1^,p2^,8);
  278. XorBlock(p2^,CV,8);
  279. Move(p2^,CV,8);
  280. p1:= pointer(longword(p1) + 8);
  281. p2:= pointer(longword(p2) + 8);
  282. end;
  283. if (Size mod 8)<> 0 then
  284. begin
  285. EncryptECB(CV,CV);
  286. Move(p1^,p2^,Size mod 8);
  287. XorBlock(p2^,CV,Size mod 8);
  288. end;
  289. end;
  290. procedure TDCP_blockcipher64.DecryptCFBblock(const Indata; var Outdata; Size: longword);
  291. var
  292. i: longword;
  293. p1, p2: Pbyte;
  294. Temp: array[0..7] of byte;
  295. begin
  296. if not fInitialized then
  297. raise EDCP_blockcipher.Create('Cipher not initialized');
  298. p1:= @Indata;
  299. p2:= @Outdata;
  300. for i:= 1 to (Size div 8) do
  301. begin
  302. Move(p1^,Temp,8);
  303. EncryptECB(CV,CV);
  304. Move(p1^,p2^,8);
  305. XorBlock(p2^,CV,8);
  306. Move(Temp,CV,8);
  307. p1:= pointer(longword(p1) + 8);
  308. p2:= pointer(longword(p2) + 8);
  309. end;
  310. if (Size mod 8)<> 0 then
  311. begin
  312. EncryptECB(CV,CV);
  313. Move(p1^,p2^,Size mod 8);
  314. XorBlock(p2^,CV,Size mod 8);
  315. end;
  316. end;
  317. procedure TDCP_blockcipher64.EncryptOFB(const Indata; var Outdata; Size: longword);
  318. var
  319. i: longword;
  320. p1, p2: pointer;
  321. begin
  322. if not fInitialized then
  323. raise EDCP_blockcipher.Create('Cipher not initialized');
  324. p1:= @Indata;
  325. p2:= @Outdata;
  326. for i:= 1 to (Size div 8) do
  327. begin
  328. EncryptECB(CV,CV);
  329. Move(p1^,p2^,8);
  330. XorBlock(p2^,CV,8);
  331. p1:= pointer(longword(p1) + 8);
  332. p2:= pointer(longword(p2) + 8);
  333. end;
  334. if (Size mod 8)<> 0 then
  335. begin
  336. EncryptECB(CV,CV);
  337. Move(p1^,p2^,Size mod 8);
  338. XorBlock(p2^,CV,Size mod 8);
  339. end;
  340. end;
  341. procedure TDCP_blockcipher64.DecryptOFB(const Indata; var Outdata; Size: longword);
  342. var
  343. i: longword;
  344. p1, p2: pointer;
  345. begin
  346. if not fInitialized then
  347. raise EDCP_blockcipher.Create('Cipher not initialized');
  348. p1:= @Indata;
  349. p2:= @Outdata;
  350. for i:= 1 to (Size div 8) do
  351. begin
  352. EncryptECB(CV,CV);
  353. Move(p1^,p2^,8);
  354. XorBlock(p2^,CV,8);
  355. p1:= pointer(longword(p1) + 8);
  356. p2:= pointer(longword(p2) + 8);
  357. end;
  358. if (Size mod 8)<> 0 then
  359. begin
  360. EncryptECB(CV,CV);
  361. Move(p1^,p2^,Size mod 8);
  362. XorBlock(p2^,CV,Size mod 8);
  363. end;
  364. end;
  365. procedure TDCP_blockcipher64.EncryptCTR(const Indata; var Outdata; Size: longword);
  366. var
  367. temp: array[0..7] of byte;
  368. i: longword;
  369. p1, p2: pointer;
  370. begin
  371. if not fInitialized then
  372. raise EDCP_blockcipher.Create('Cipher not initialized');
  373. p1:= @Indata;
  374. p2:= @Outdata;
  375. for i:= 1 to (Size div 8) do
  376. begin
  377. EncryptECB(CV,temp);
  378. IncCounter;
  379. Move(p1^,p2^,8);
  380. XorBlock(p2^,temp,8);
  381. p1:= pointer(longword(p1) + 8);
  382. p2:= pointer(longword(p2) + 8);
  383. end;
  384. if (Size mod 8)<> 0 then
  385. begin
  386. EncryptECB(CV,temp);
  387. IncCounter;
  388. Move(p1^,p2^,Size mod 8);
  389. XorBlock(p2^,temp,Size mod 8);
  390. end;
  391. end;
  392. procedure TDCP_blockcipher64.DecryptCTR(const Indata; var Outdata; Size: longword);
  393. var
  394. temp: array[0..7] of byte;
  395. i: longword;
  396. p1, p2: pointer;
  397. begin
  398. if not fInitialized then
  399. raise EDCP_blockcipher.Create('Cipher not initialized');
  400. p1:= @Indata;
  401. p2:= @Outdata;
  402. for i:= 1 to (Size div 8) do
  403. begin
  404. EncryptECB(CV,temp);
  405. IncCounter;
  406. Move(p1^,p2^,8);
  407. XorBlock(p2^,temp,8);
  408. p1:= pointer(longword(p1) + 8);
  409. p2:= pointer(longword(p2) + 8);
  410. end;
  411. if (Size mod 8)<> 0 then
  412. begin
  413. EncryptECB(CV,temp);
  414. IncCounter;
  415. Move(p1^,p2^,Size mod 8);
  416. XorBlock(p2^,temp,Size mod 8);
  417. end;
  418. end;
  419. {** TDCP_blockcipher128 ********************************************************}
  420. procedure TDCP_blockcipher128.IncCounter;
  421. var
  422. i: integer;
  423. begin
  424. Inc(CV[15]);
  425. i:= 15;
  426. while (i> 0) and (CV[i] = 0) do
  427. begin
  428. Inc(CV[i-1]);
  429. Dec(i);
  430. end;
  431. end;
  432. class function TDCP_blockcipher128.GetBlockSize: integer;
  433. begin
  434. Result:= 128;
  435. end;
  436. procedure TDCP_blockcipher128.Init(const Key; Size: longword; InitVector: pointer);
  437. begin
  438. inherited Init(Key,Size,InitVector);
  439. InitKey(Key,Size);
  440. if InitVector= nil then
  441. begin
  442. FillChar(IV,16,{$IFDEF DCP1COMPAT}$FF{$ELSE}0{$ENDIF});
  443. EncryptECB(IV,IV);
  444. Reset;
  445. end
  446. else
  447. begin
  448. Move(InitVector^,IV,16);
  449. Reset;
  450. end;
  451. end;
  452. procedure TDCP_blockcipher128.SetIV(const Value);
  453. begin
  454. if not fInitialized then
  455. raise EDCP_blockcipher.Create('Cipher not initialized');
  456. Move(Value,IV,16);
  457. Reset;
  458. end;
  459. procedure TDCP_blockcipher128.GetIV(var Value);
  460. begin
  461. if not fInitialized then
  462. raise EDCP_blockcipher.Create('Cipher not initialized');
  463. Move(CV,Value,16);
  464. end;
  465. procedure TDCP_blockcipher128.Reset;
  466. begin
  467. if not fInitialized then
  468. raise EDCP_blockcipher.Create('Cipher not initialized')
  469. else
  470. Move(IV,CV,16);
  471. end;
  472. procedure TDCP_blockcipher128.Burn;
  473. begin
  474. FillChar(IV,16,$FF);
  475. FillChar(CV,16,$FF);
  476. inherited Burn;
  477. end;
  478. procedure TDCP_blockcipher128.EncryptCBC(const Indata; var Outdata; Size: longword);
  479. var
  480. i: longword;
  481. p1, p2: pointer;
  482. begin
  483. if not fInitialized then
  484. raise EDCP_blockcipher.Create('Cipher not initialized');
  485. p1:= @Indata;
  486. p2:= @Outdata;
  487. for i:= 1 to (Size div 16) do
  488. begin
  489. Move(p1^,p2^,16);
  490. XorBlock(p2^,CV,16);
  491. EncryptECB(p2^,p2^);
  492. Move(p2^,CV,16);
  493. p1:= pointer(longword(p1) + 16);
  494. p2:= pointer(longword(p2) + 16);
  495. end;
  496. if (Size mod 16)<> 0 then
  497. begin
  498. EncryptECB(CV,CV);
  499. Move(p1^,p2^,Size mod 16);
  500. XorBlock(p2^,CV,Size mod 16);
  501. end;
  502. end;
  503. procedure TDCP_blockcipher128.DecryptCBC(const Indata; var Outdata; Size: longword);
  504. var
  505. i: longword;
  506. p1, p2: pointer;
  507. Temp: array[0..15] of byte;
  508. begin
  509. if not fInitialized then
  510. raise EDCP_blockcipher.Create('Cipher not initialized');
  511. p1:= @Indata;
  512. p2:= @Outdata;
  513. for i:= 1 to (Size div 16) do
  514. begin
  515. Move(p1^,p2^,16);
  516. Move(p1^,Temp,16);
  517. DecryptECB(p2^,p2^);
  518. XorBlock(p2^,CV,16);
  519. Move(Temp,CV,16);
  520. p1:= pointer(longword(p1) + 16);
  521. p2:= pointer(longword(p2) + 16);
  522. end;
  523. if (Size mod 16)<> 0 then
  524. begin
  525. EncryptECB(CV,CV);
  526. Move(p1^,p2^,Size mod 16);
  527. XorBlock(p2^,CV,Size mod 16);
  528. end;
  529. end;
  530. procedure TDCP_blockcipher128.EncryptCFB8bit(const Indata; var Outdata; Size: longword);
  531. var
  532. i: longword;
  533. p1, p2: Pbyte;
  534. Temp: array[0..15] of byte;
  535. begin
  536. if not fInitialized then
  537. raise EDCP_blockcipher.Create('Cipher not initialized');
  538. p1:= @Indata;
  539. p2:= @Outdata;
  540. for i:= 1 to Size do
  541. begin
  542. EncryptECB(CV,Temp);
  543. p2^:= p1^ xor Temp[0];
  544. Move(CV[1],CV[0],15);
  545. CV[15]:= p2^;
  546. Inc(p1);
  547. Inc(p2);
  548. end;
  549. end;
  550. procedure TDCP_blockcipher128.DecryptCFB8bit(const Indata; var Outdata; Size: longword);
  551. var
  552. i: longword;
  553. p1, p2: Pbyte;
  554. TempByte: byte;
  555. Temp: array[0..15] of byte;
  556. begin
  557. if not fInitialized then
  558. raise EDCP_blockcipher.Create('Cipher not initialized');
  559. p1:= @Indata;
  560. p2:= @Outdata;
  561. for i:= 1 to Size do
  562. begin
  563. TempByte:= p1^;
  564. EncryptECB(CV,Temp);
  565. p2^:= p1^ xor Temp[0];
  566. Move(CV[1],CV[0],15);
  567. CV[15]:= TempByte;
  568. Inc(p1);
  569. Inc(p2);
  570. end;
  571. end;
  572. procedure TDCP_blockcipher128.EncryptCFBblock(const Indata; var Outdata; Size: longword);
  573. var
  574. i: longword;
  575. p1, p2: Pbyte;
  576. begin
  577. if not fInitialized then
  578. raise EDCP_blockcipher.Create('Cipher not initialized');
  579. p1:= @Indata;
  580. p2:= @Outdata;
  581. for i:= 1 to (Size div 16) do
  582. begin
  583. EncryptECB(CV,CV);
  584. Move(p1^,p2^,16);
  585. XorBlock(p2^,CV,16);
  586. Move(p2^,CV,16);
  587. p1:= pointer(longword(p1) + 16);
  588. p2:= pointer(longword(p2) + 16);
  589. end;
  590. if (Size mod 16)<> 0 then
  591. begin
  592. EncryptECB(CV,CV);
  593. Move(p1^,p2^,Size mod 16);
  594. XorBlock(p2^,CV,Size mod 16);
  595. end;
  596. end;
  597. procedure TDCP_blockcipher128.DecryptCFBblock(const Indata; var Outdata; Size: longword);
  598. var
  599. i: longword;
  600. p1, p2: Pbyte;
  601. Temp: array[0..15] of byte;
  602. begin
  603. if not fInitialized then
  604. raise EDCP_blockcipher.Create('Cipher not initialized');
  605. p1:= @Indata;
  606. p2:= @Outdata;
  607. for i:= 1 to (Size div 16) do
  608. begin
  609. Move(p1^,Temp,16);
  610. EncryptECB(CV,CV);
  611. Move(p1^,p2^,16);
  612. XorBlock(p2^,CV,16);
  613. Move(Temp,CV,16);
  614. p1:= pointer(longword(p1) + 16);
  615. p2:= pointer(longword(p2) + 16);
  616. end;
  617. if (Size mod 16)<> 0 then
  618. begin
  619. EncryptECB(CV,CV);
  620. Move(p1^,p2^,Size mod 16);
  621. XorBlock(p2^,CV,Size mod 16);
  622. end;
  623. end;
  624. procedure TDCP_blockcipher128.EncryptOFB(const Indata; var Outdata; Size: longword);
  625. var
  626. i: longword;
  627. p1, p2: pointer;
  628. begin
  629. if not fInitialized then
  630. raise EDCP_blockcipher.Create('Cipher not initialized');
  631. p1:= @Indata;
  632. p2:= @Outdata;
  633. for i:= 1 to (Size div 16) do
  634. begin
  635. EncryptECB(CV,CV);
  636. Move(p1^,p2^,16);
  637. XorBlock(p2^,CV,16);
  638. p1:= pointer(longword(p1) + 16);
  639. p2:= pointer(longword(p2) + 16);
  640. end;
  641. if (Size mod 16)<> 0 then
  642. begin
  643. EncryptECB(CV,CV);
  644. Move(p1^,p2^,Size mod 16);
  645. XorBlock(p2^,CV,Size mod 16);
  646. end;
  647. end;
  648. procedure TDCP_blockcipher128.DecryptOFB(const Indata; var Outdata; Size: longword);
  649. var
  650. i: longword;
  651. p1, p2: pointer;
  652. begin
  653. if not fInitialized then
  654. raise EDCP_blockcipher.Create('Cipher not initialized');
  655. p1:= @Indata;
  656. p2:= @Outdata;
  657. for i:= 1 to (Size div 16) do
  658. begin
  659. EncryptECB(CV,CV);
  660. Move(p1^,p2^,16);
  661. XorBlock(p2^,CV,16);
  662. p1:= pointer(longword(p1) + 16);
  663. p2:= pointer(longword(p2) + 16);
  664. end;
  665. if (Size mod 16)<> 0 then
  666. begin
  667. EncryptECB(CV,CV);
  668. Move(p1^,p2^,Size mod 16);
  669. XorBlock(p2^,CV,Size mod 16);
  670. end;
  671. end;
  672. procedure TDCP_blockcipher128.EncryptCTR(const Indata; var Outdata; Size: longword);
  673. var
  674. temp: array[0..15] of byte;
  675. i: longword;
  676. p1, p2: pointer;
  677. begin
  678. if not fInitialized then
  679. raise EDCP_blockcipher.Create('Cipher not initialized');
  680. p1:= @Indata;
  681. p2:= @Outdata;
  682. for i:= 1 to (Size div 16) do
  683. begin
  684. EncryptECB(CV,temp);
  685. IncCounter;
  686. Move(p1^,p2^,16);
  687. XorBlock(p2^,temp,16);
  688. p1:= pointer(longword(p1) + 16);
  689. p2:= pointer(longword(p2) + 16);
  690. end;
  691. if (Size mod 16)<> 0 then
  692. begin
  693. EncryptECB(CV,temp);
  694. IncCounter;
  695. Move(p1^,p2^,Size mod 16);
  696. XorBlock(p2^,temp,Size mod 16);
  697. end;
  698. end;
  699. procedure TDCP_blockcipher128.DecryptCTR(const Indata; var Outdata; Size: longword);
  700. var
  701. temp: array[0..15] of byte;
  702. i: longword;
  703. p1, p2: pointer;
  704. begin
  705. if not fInitialized then
  706. raise EDCP_blockcipher.Create('Cipher not initialized');
  707. p1:= @Indata;
  708. p2:= @Outdata;
  709. for i:= 1 to (Size div 16) do
  710. begin
  711. EncryptECB(CV,temp);
  712. IncCounter;
  713. Move(p1^,p2^,16);
  714. XorBlock(p2^,temp,16);
  715. p1:= pointer(longword(p1) + 16);
  716. p2:= pointer(longword(p2) + 16);
  717. end;
  718. if (Size mod 16)<> 0 then
  719. begin
  720. EncryptECB(CV,temp);
  721. IncCounter;
  722. Move(p1^,p2^,Size mod 16);
  723. XorBlock(p2^,temp,Size mod 16);
  724. end;
  725. end;
  726. end.