blowfish.pp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {
  11. Unit implementing simple blowfish algorithm
  12. }
  13. {$ifdef fpc}
  14. {$mode objfpc}
  15. {$h+}
  16. {$inline on}
  17. {$endif}
  18. unit BlowFish;
  19. interface
  20. uses SysUtils,Classes;
  21. Const
  22. BFRounds = 16; { 16 blowfish rounds }
  23. Type
  24. PBlowFishKey = ^TBlowFishKey;
  25. TBlowFishKey = array[0..55] of Byte;
  26. TBFBlock = array[0..1] of LongInt; { BlowFish }
  27. type
  28. TBlowFish = Class(TObject)
  29. Private
  30. PBox : array[0..(BFRounds+1)] of LongInt;
  31. SBox : array[0..3, 0..255] of LongInt;
  32. Function F(x : Cardinal) : Cardinal;{$ifdef fpc}inline;{$endif}
  33. Public
  34. Constructor Create(Key : TBlowFishKey; KeySize : Integer);
  35. Procedure Encrypt(var Block : TBFBlock);
  36. Procedure Decrypt(var Block : TBFBlock);
  37. end;
  38. Type
  39. EBlowFishError = Class(EStreamError);
  40. { TBlowFishStream }
  41. TBlowFishStream = Class(TOwnerStream)
  42. Private
  43. FBF : TBlowFish;
  44. FData : TBFBlock;
  45. FBufpos : Byte;
  46. FPos : Int64;
  47. Public
  48. Constructor Create(AKey : TBlowFishKey; AKeySize : Byte; Dest: TStream);
  49. Constructor Create(Const KeyPhrase : String; Dest: TStream);
  50. Destructor Destroy; override;
  51. Property BlowFish : TBlowFish Read FBF;
  52. end;
  53. TBlowFishEncryptStream = Class(TBlowFishStream)
  54. public
  55. Destructor Destroy; override;
  56. function Write(const Buffer; Count: Longint): Longint; override;
  57. function Seek(Offset: Longint; Origin: Word): Longint; override;
  58. procedure Flush;
  59. end;
  60. TBlowFishDeCryptStream = Class(TBlowFishStream)
  61. public
  62. function Read(var Buffer; Count: Longint): Longint; override;
  63. function Seek(Offset: Longint; Origin: Word): Longint; override;
  64. end;
  65. Implementation
  66. ResourceString
  67. SNoSeekAllowed = 'Seek not allowed on encryption streams';
  68. SErrEmptyPassPhraseNotAllowed = 'Empty passphrase is not allowed in constructor';
  69. { Blowfish lookup tables }
  70. const
  71. bf_P: array[0..(BFRounds + 1)] of DWord = (
  72. $243F6A88, $85A308D3, $13198A2E, $03707344,
  73. $A4093822, $299F31D0, $082EFA98, $EC4E6C89,
  74. $452821E6, $38D01377, $BE5466CF, $34E90C6C,
  75. $C0AC29B7, $C97C50DD, $3F84D5B5, $B5470917,
  76. $9216D5D9, $8979FB1B);
  77. const
  78. bf_S: array[0..3, 0..255] of DWord =
  79. (
  80. ( $D1310BA6, $98DFB5AC, $2FFD72DB, $D01ADFB7,
  81. $B8E1AFED, $6A267E96, $BA7C9045, $F12C7F99,
  82. $24A19947, $B3916CF7, $0801F2E2, $858EFC16,
  83. $636920D8, $71574E69, $A458FEA3, $F4933D7E,
  84. $0D95748F, $728EB658, $718BCD58, $82154AEE,
  85. $7B54A41D, $C25A59B5, $9C30D539, $2AF26013,
  86. $C5D1B023, $286085F0, $CA417918, $B8DB38EF,
  87. $8E79DCB0, $603A180E, $6C9E0E8B, $B01E8A3E,
  88. $D71577C1, $BD314B27, $78AF2FDA, $55605C60,
  89. $E65525F3, $AA55AB94, $57489862, $63E81440,
  90. $55CA396A, $2AAB10B6, $B4CC5C34, $1141E8CE,
  91. $A15486AF, $7C72E993, $B3EE1411, $636FBC2A,
  92. $2BA9C55D, $741831F6, $CE5C3E16, $9B87931E,
  93. $AFD6BA33, $6C24CF5C, $7A325381, $28958677,
  94. $3B8F4898, $6B4BB9AF, $C4BFE81B, $66282193,
  95. $61D809CC, $FB21A991, $487CAC60, $5DEC8032,
  96. $EF845D5D, $E98575B1, $DC262302, $EB651B88,
  97. $23893E81, $D396ACC5, $0F6D6FF3, $83F44239,
  98. $2E0B4482, $A4842004, $69C8F04A, $9E1F9B5E,
  99. $21C66842, $F6E96C9A, $670C9C61, $ABD388F0,
  100. $6A51A0D2, $D8542F68, $960FA728, $AB5133A3,
  101. $6EEF0B6C, $137A3BE4, $BA3BF050, $7EFB2A98,
  102. $A1F1651D, $39AF0176, $66CA593E, $82430E88,
  103. $8CEE8619, $456F9FB4, $7D84A5C3, $3B8B5EBE,
  104. $E06F75D8, $85C12073, $401A449F, $56C16AA6,
  105. $4ED3AA62, $363F7706, $1BFEDF72, $429B023D,
  106. $37D0D724, $D00A1248, $DB0FEAD3, $49F1C09B,
  107. $075372C9, $80991B7B, $25D479D8, $F6E8DEF7,
  108. $E3FE501A, $B6794C3B, $976CE0BD, $04C006BA,
  109. $C1A94FB6, $409F60C4, $5E5C9EC2, $196A2463,
  110. $68FB6FAF, $3E6C53B5, $1339B2EB, $3B52EC6F,
  111. $6DFC511F, $9B30952C, $CC814544, $AF5EBD09,
  112. $BEE3D004, $DE334AFD, $660F2807, $192E4BB3,
  113. $C0CBA857, $45C8740F, $D20B5F39, $B9D3FBDB,
  114. $5579C0BD, $1A60320A, $D6A100C6, $402C7279,
  115. $679F25FE, $FB1FA3CC, $8EA5E9F8, $DB3222F8,
  116. $3C7516DF, $FD616B15, $2F501EC8, $AD0552AB,
  117. $323DB5FA, $FD238760, $53317B48, $3E00DF82,
  118. $9E5C57BB, $CA6F8CA0, $1A87562E, $DF1769DB,
  119. $D542A8F6, $287EFFC3, $AC6732C6, $8C4F5573,
  120. $695B27B0, $BBCA58C8, $E1FFA35D, $B8F011A0,
  121. $10FA3D98, $FD2183B8, $4AFCB56C, $2DD1D35B,
  122. $9A53E479, $B6F84565, $D28E49BC, $4BFB9790,
  123. $E1DDF2DA, $A4CB7E33, $62FB1341, $CEE4C6E8,
  124. $EF20CADA, $36774C01, $D07E9EFE, $2BF11FB4,
  125. $95DBDA4D, $AE909198, $EAAD8E71, $6B93D5A0,
  126. $D08ED1D0, $AFC725E0, $8E3C5B2F, $8E7594B7,
  127. $8FF6E2FB, $F2122B64, $8888B812, $900DF01C,
  128. $4FAD5EA0, $688FC31C, $D1CFF191, $B3A8C1AD,
  129. $2F2F2218, $BE0E1777, $EA752DFE, $8B021FA1,
  130. $E5A0CC0F, $B56F74E8, $18ACF3D6, $CE89E299,
  131. $B4A84FE0, $FD13E0B7, $7CC43B81, $D2ADA8D9,
  132. $165FA266, $80957705, $93CC7314, $211A1477,
  133. $E6AD2065, $77B5FA86, $C75442F5, $FB9D35CF,
  134. $EBCDAF0C, $7B3E89A0, $D6411BD3, $AE1E7E49,
  135. $00250E2D, $2071B35E, $226800BB, $57B8E0AF,
  136. $2464369B, $F009B91E, $5563911D, $59DFA6AA,
  137. $78C14389, $D95A537F, $207D5BA2, $02E5B9C5,
  138. $83260376, $6295CFA9, $11C81968, $4E734A41,
  139. $B3472DCA, $7B14A94A, $1B510052, $9A532915,
  140. $D60F573F, $BC9BC6E4, $2B60A476, $81E67400,
  141. $08BA6FB5, $571BE91F, $F296EC6B, $2A0DD915,
  142. $B6636521, $E7B9F9B6, $FF34052E, $C5855664,
  143. $53B02D5D, $A99F8FA1, $08BA4799, $6E85076A),
  144. {SECOND 256}
  145. ($4B7A70E9, $B5B32944, $DB75092E, $C4192623,
  146. $AD6EA6B0, $49A7DF7D, $9CEE60B8, $8FEDB266,
  147. $ECAA8C71, $699A17FF, $5664526C, $C2B19EE1,
  148. $193602A5, $75094C29, $A0591340, $E4183A3E,
  149. $3F54989A, $5B429D65, $6B8FE4D6, $99F73FD6,
  150. $A1D29C07, $EFE830F5, $4D2D38E6, $F0255DC1,
  151. $4CDD2086, $8470EB26, $6382E9C6, $021ECC5E,
  152. $09686B3F, $3EBAEFC9, $3C971814, $6B6A70A1,
  153. $687F3584, $52A0E286, $B79C5305, $AA500737,
  154. $3E07841C, $7FDEAE5C, $8E7D44EC, $5716F2B8,
  155. $B03ADA37, $F0500C0D, $F01C1F04, $0200B3FF,
  156. $AE0CF51A, $3CB574B2, $25837A58, $DC0921BD,
  157. $D19113F9, $7CA92FF6, $94324773, $22F54701,
  158. $3AE5E581, $37C2DADC, $C8B57634, $9AF3DDA7,
  159. $A9446146, $0FD0030E, $ECC8C73E, $A4751E41,
  160. $E238CD99, $3BEA0E2F, $3280BBA1, $183EB331,
  161. $4E548B38, $4F6DB908, $6F420D03, $F60A04BF,
  162. $2CB81290, $24977C79, $5679B072, $BCAF89AF,
  163. $DE9A771F, $D9930810, $B38BAE12, $DCCF3F2E,
  164. $5512721F, $2E6B7124, $501ADDE6, $9F84CD87,
  165. $7A584718, $7408DA17, $BC9F9ABC, $E94B7D8C,
  166. $EC7AEC3A, $DB851DFA, $63094366, $C464C3D2,
  167. $EF1C1847, $3215D908, $DD433B37, $24C2BA16,
  168. $12A14D43, $2A65C451, $50940002, $133AE4DD,
  169. $71DFF89E, $10314E55, $81AC77D6, $5F11199B,
  170. $043556F1, $D7A3C76B, $3C11183B, $5924A509,
  171. $F28FE6ED, $97F1FBFA, $9EBABF2C, $1E153C6E,
  172. $86E34570, $EAE96FB1, $860E5E0A, $5A3E2AB3,
  173. $771FE71C, $4E3D06FA, $2965DCB9, $99E71D0F,
  174. $803E89D6, $5266C825, $2E4CC978, $9C10B36A,
  175. $C6150EBA, $94E2EA78, $A5FC3C53, $1E0A2DF4,
  176. $F2F74EA7, $361D2B3D, $1939260F, $19C27960,
  177. $5223A708, $F71312B6, $EBADFE6E, $EAC31F66,
  178. $E3BC4595, $A67BC883, $B17F37D1, $018CFF28,
  179. $C332DDEF, $BE6C5AA5, $65582185, $68AB9802,
  180. $EECEA50F, $DB2F953B, $2AEF7DAD, $5B6E2F84,
  181. $1521B628, $29076170, $ECDD4775, $619F1510,
  182. $13CCA830, $EB61BD96, $0334FE1E, $AA0363CF,
  183. $B5735C90, $4C70A239, $D59E9E0B, $CBAADE14,
  184. $EECC86BC, $60622CA7, $9CAB5CAB, $B2F3846E,
  185. $648B1EAF, $19BDF0CA, $A02369B9, $655ABB50,
  186. $40685A32, $3C2AB4B3, $319EE9D5, $C021B8F7,
  187. $9B540B19, $875FA099, $95F7997E, $623D7DA8,
  188. $F837889A, $97E32D77, $11ED935F, $16681281,
  189. $0E358829, $C7E61FD6, $96DEDFA1, $7858BA99,
  190. $57F584A5, $1B227263, $9B83C3FF, $1AC24696,
  191. $CDB30AEB, $532E3054, $8FD948E4, $6DBC3128,
  192. $58EBF2EF, $34C6FFEA, $FE28ED61, $EE7C3C73,
  193. $5D4A14D9, $E864B7E3, $42105D14, $203E13E0,
  194. $45EEE2B6, $A3AAABEA, $DB6C4F15, $FACB4FD0,
  195. $C742F442, $EF6ABBB5, $654F3B1D, $41CD2105,
  196. $D81E799E, $86854DC7, $E44B476A, $3D816250,
  197. $CF62A1F2, $5B8D2646, $FC8883A0, $C1C7B6A3,
  198. $7F1524C3, $69CB7492, $47848A0B, $5692B285,
  199. $095BBF00, $AD19489D, $1462B174, $23820E00,
  200. $58428D2A, $0C55F5EA, $1DADF43E, $233F7061,
  201. $3372F092, $8D937E41, $D65FECF1, $6C223BDB,
  202. $7CDE3759, $CBEE7460, $4085F2A7, $CE77326E,
  203. $A6078084, $19F8509E, $E8EFD855, $61D99735,
  204. $A969A7AA, $C50C06C2, $5A04ABFC, $800BCADC,
  205. $9E447A2E, $C3453484, $FDD56705, $0E1E9EC9,
  206. $DB73DBD3, $105588CD, $675FDA79, $E3674340,
  207. $C5C43465, $713E38D8, $3D28F89E, $F16DFF20,
  208. $153E21E7, $8FB03D4A, $E6E39F2B, $DB83ADF7),
  209. {THIRD 256}
  210. ($E93D5A68, $948140F7, $F64C261C, $94692934,
  211. $411520F7, $7602D4F7, $BCF46B2E, $D4A20068,
  212. $D4082471, $3320F46A, $43B7D4B7, $500061AF,
  213. $1E39F62E, $97244546, $14214F74, $BF8B8840,
  214. $4D95FC1D, $96B591AF, $70F4DDD3, $66A02F45,
  215. $BFBC09EC, $03BD9785, $7FAC6DD0, $31CB8504,
  216. $96EB27B3, $55FD3941, $DA2547E6, $ABCA0A9A,
  217. $28507825, $530429F4, $0A2C86DA, $E9B66DFB,
  218. $68DC1462, $D7486900, $680EC0A4, $27A18DEE,
  219. $4F3FFEA2, $E887AD8C, $B58CE006, $7AF4D6B6,
  220. $AACE1E7C, $D3375FEC, $CE78A399, $406B2A42,
  221. $20FE9E35, $D9F385B9, $EE39D7AB, $3B124E8B,
  222. $1DC9FAF7, $4B6D1856, $26A36631, $EAE397B2,
  223. $3A6EFA74, $DD5B4332, $6841E7F7, $CA7820FB,
  224. $FB0AF54E, $D8FEB397, $454056AC, $BA489527,
  225. $55533A3A, $20838D87, $FE6BA9B7, $D096954B,
  226. $55A867BC, $A1159A58, $CCA92963, $99E1DB33,
  227. $A62A4A56, $3F3125F9, $5EF47E1C, $9029317C,
  228. $FDF8E802, $04272F70, $80BB155C, $05282CE3,
  229. $95C11548, $E4C66D22, $48C1133F, $C70F86DC,
  230. $07F9C9EE, $41041F0F, $404779A4, $5D886E17,
  231. $325F51EB, $D59BC0D1, $F2BCC18F, $41113564,
  232. $257B7834, $602A9C60, $DFF8E8A3, $1F636C1B,
  233. $0E12B4C2, $02E1329E, $AF664FD1, $CAD18115,
  234. $6B2395E0, $333E92E1, $3B240B62, $EEBEB922,
  235. $85B2A20E, $E6BA0D99, $DE720C8C, $2DA2F728,
  236. $D0127845, $95B794FD, $647D0862, $E7CCF5F0,
  237. $5449A36F, $877D48FA, $C39DFD27, $F33E8D1E,
  238. $0A476341, $992EFF74, $3A6F6EAB, $F4F8FD37,
  239. $A812DC60, $A1EBDDF8, $991BE14C, $DB6E6B0D,
  240. $C67B5510, $6D672C37, $2765D43B, $DCD0E804,
  241. $F1290DC7, $CC00FFA3, $B5390F92, $690FED0B,
  242. $667B9FFB, $CEDB7D9C, $A091CF0B, $D9155EA3,
  243. $BB132F88, $515BAD24, $7B9479BF, $763BD6EB,
  244. $37392EB3, $CC115979, $8026E297, $F42E312D,
  245. $6842ADA7, $C66A2B3B, $12754CCC, $782EF11C,
  246. $6A124237, $B79251E7, $06A1BBE6, $4BFB6350,
  247. $1A6B1018, $11CAEDFA, $3D25BDD8, $E2E1C3C9,
  248. $44421659, $0A121386, $D90CEC6E, $D5ABEA2A,
  249. $64AF674E, $DA86A85F, $BEBFE988, $64E4C3FE,
  250. $9DBC8057, $F0F7C086, $60787BF8, $6003604D,
  251. $D1FD8346, $F6381FB0, $7745AE04, $D736FCCC,
  252. $83426B33, $F01EAB71, $B0804187, $3C005E5F,
  253. $77A057BE, $BDE8AE24, $55464299, $BF582E61,
  254. $4E58F48F, $F2DDFDA2, $F474EF38, $8789BDC2,
  255. $5366F9C3, $C8B38E74, $B475F255, $46FCD9B9,
  256. $7AEB2661, $8B1DDF84, $846A0E79, $915F95E2,
  257. $466E598E, $20B45770, $8CD55591, $C902DE4C,
  258. $B90BACE1, $BB8205D0, $11A86248, $7574A99E,
  259. $B77F19B6, $E0A9DC09, $662D09A1, $C4324633,
  260. $E85A1F02, $09F0BE8C, $4A99A025, $1D6EFE10,
  261. $1AB93D1D, $0BA5A4DF, $A186F20F, $2868F169,
  262. $DCB7DA83, $573906FE, $A1E2CE9B, $4FCD7F52,
  263. $50115E01, $A70683FA, $A002B5C4, $0DE6D027,
  264. $9AF88C27, $773F8641, $C3604C06, $61A806B5,
  265. $F0177A28, $C0F586E0, $006058AA, $30DC7D62,
  266. $11E69ED7, $2338EA63, $53C2DD94, $C2C21634,
  267. $BBCBEE56, $90BCB6DE, $EBFC7DA1, $CE591D76,
  268. $6F05E409, $4B7C0188, $39720A3D, $7C927C24,
  269. $86E3725F, $724D9DB9, $1AC15BB4, $D39EB8FC,
  270. $ED545578, $08FCA5B5, $D83D7CD3, $4DAD0FC4,
  271. $1E50EF5E, $B161E6F8, $A28514D9, $6C51133C,
  272. $6FD5C7E7, $56E14EC4, $362ABFCE, $DDC6C837,
  273. $D79A3234, $92638212, $670EFA8E, $406000E0),
  274. {FOURTH 256}
  275. ($3A39CE37, $D3FAF5CF, $ABC27737, $5AC52D1B,
  276. $5CB0679E, $4FA33742, $D3822740, $99BC9BBE,
  277. $D5118E9D, $BF0F7315, $D62D1C7E, $C700C47B,
  278. $B78C1B6B, $21A19045, $B26EB1BE, $6A366EB4,
  279. $5748AB2F, $BC946E79, $C6A376D2, $6549C2C8,
  280. $530FF8EE, $468DDE7D, $D5730A1D, $4CD04DC6,
  281. $2939BBDB, $A9BA4650, $AC9526E8, $BE5EE304,
  282. $A1FAD5F0, $6A2D519A, $63EF8CE2, $9A86EE22,
  283. $C089C2B8, $43242EF6, $A51E03AA, $9CF2D0A4,
  284. $83C061BA, $9BE96A4D, $8FE51550, $BA645BD6,
  285. $2826A2F9, $A73A3AE1, $4BA99586, $EF5562E9,
  286. $C72FEFD3, $F752F7DA, $3F046F69, $77FA0A59,
  287. $80E4A915, $87B08601, $9B09E6AD, $3B3EE593,
  288. $E990FD5A, $9E34D797, $2CF0B7D9, $022B8B51,
  289. $96D5AC3A, $017DA67D, $D1CF3ED6, $7C7D2D28,
  290. $1F9F25CF, $ADF2B89B, $5AD6B472, $5A88F54C,
  291. $E029AC71, $E019A5E6, $47B0ACFD, $ED93FA9B,
  292. $E8D3C48D, $283B57CC, $F8D56629, $79132E28,
  293. $785F0191, $ED756055, $F7960E44, $E3D35E8C,
  294. $15056DD4, $88F46DBA, $03A16125, $0564F0BD,
  295. $C3EB9E15, $3C9057A2, $97271AEC, $A93A072A,
  296. $1B3F6D9B, $1E6321F5, $F59C66FB, $26DCF319,
  297. $7533D928, $B155FDF5, $03563482, $8ABA3CBB,
  298. $28517711, $C20AD9F8, $ABCC5167, $CCAD925F,
  299. $4DE81751, $3830DC8E, $379D5862, $9320F991,
  300. $EA7A90C2, $FB3E7BCE, $5121CE64, $774FBE32,
  301. $A8B6E37E, $C3293D46, $48DE5369, $6413E680,
  302. $A2AE0810, $DD6DB224, $69852DFD, $09072166,
  303. $B39A460A, $6445C0DD, $586CDECF, $1C20C8AE,
  304. $5BBEF7DD, $1B588D40, $CCD2017F, $6BB4E3BB,
  305. $DDA26A7E, $3A59FF45, $3E350A44, $BCB4CDD5,
  306. $72EACEA8, $FA6484BB, $8D6612AE, $BF3C6F47,
  307. $D29BE463, $542F5D9E, $AEC2771B, $F64E6370,
  308. $740E0D8D, $E75B1357, $F8721671, $AF537D5D,
  309. $4040CB08, $4EB4E2CC, $34D2466A, $0115AF84,
  310. $E1B00428, $95983A1D, $06B89FB4, $CE6EA048,
  311. $6F3F3B82, $3520AB82, $011A1D4B, $277227F8,
  312. $611560B1, $E7933FDC, $BB3A792B, $344525BD,
  313. $A08839E1, $51CE794B, $2F32C9B7, $A01FBAC9,
  314. $E01CC87E, $BCC7D1F6, $CF0111C3, $A1E8AAC7,
  315. $1A908749, $D44FBD9A, $D0DADECB, $D50ADA38,
  316. $0339C32A, $C6913667, $8DF9317C, $E0B12B4F,
  317. $F79E59B7, $43F5BB3A, $F2D519FF, $27D9459C,
  318. $BF97222C, $15E6FC2A, $0F91FC71, $9B941525,
  319. $FAE59361, $CEB69CEB, $C2A86459, $12BAA8D1,
  320. $B6C1075E, $E3056A0C, $10D25065, $CB03A442,
  321. $E0EC6E0E, $1698DB3B, $4C98A0BE, $3278E964,
  322. $9F1F9532, $E0D392DF, $D3A0342B, $8971F21E,
  323. $1B0A7441, $4BA3348C, $C5BE7120, $C37632D8,
  324. $DF359F8D, $9B992F2E, $E60B6F47, $0FE3F11D,
  325. $E54CDA54, $1EDAD891, $CE6279CF, $CD3E7E6F,
  326. $1618B166, $FD2C1D05, $848FD2C5, $F6FB2299,
  327. $F523F357, $A6327623, $93A83531, $56CCCD02,
  328. $ACF08162, $5A75EBB5, $6E163697, $88D273CC,
  329. $DE966292, $81B949D0, $4C50901B, $71C65614,
  330. $E6C6C7BD, $327A140A, $45E1D006, $C3F27B9A,
  331. $C9AA53FD, $62A80F00, $BB25BFE2, $35BDD2F6,
  332. $71126905, $B2040222, $B6CBCF7C, $CD769C2B,
  333. $53113EC0, $1640E3D3, $38ABBD60, $2547ADF0,
  334. $BA38209C, $F746CE76, $77AFA1C5, $20756060,
  335. $85CBFE4E, $8AE88DD8, $7AAAF9B0, $4CF9AA7E,
  336. $1948C25C, $02FB8A8C, $01C36AE4, $D6EBE1F9,
  337. $90D4F869, $A65CDEA0, $3F09252D, $C208E69F,
  338. $B74E6132, $CE77E25B, $578FDFE3, $3AC372E6)
  339. );
  340. Constructor TBlowFish.Create(Key : TBlowFishKey; KeySize : Integer);
  341. var
  342. I : Integer;
  343. J : Integer;
  344. K : Integer;
  345. Data : Cardinal;
  346. Block : TBFBlock;
  347. begin
  348. Move(bf_P, PBox, SizeOf(PBox));
  349. Move(bf_S, SBox, SizeOf(SBox));
  350. { update PArray with the key bits }
  351. J := 0;
  352. for I := 0 to (BFRounds+1) do begin
  353. Data := 0;
  354. for K := 0 to 3 do begin
  355. Data := (Data shl 8) or Key[J];
  356. Inc(J);
  357. if J >= KeySize then
  358. J := 0;
  359. end;
  360. PBox[I] := PBox[I] xor Data;
  361. end;
  362. { Encrypt all-zero block}
  363. Block[0] := 0;
  364. Block[1] := 0;
  365. I := 0;
  366. repeat
  367. Encrypt(Block);
  368. PBox[I] := Block[0];
  369. PBox[I+1] := Block[1];
  370. Inc(I, 2);
  371. until I > BFRounds+1;
  372. { Now continue with rest }
  373. for J := 0 to 3 do begin
  374. I := 0;
  375. repeat
  376. Encrypt(Block);
  377. SBox[J, I] := Block[0];
  378. SBox[J, I+1] := Block[1];
  379. Inc(I, 2);
  380. until I > 255;
  381. end;
  382. end;
  383. Function TBlowFish.F(x : Cardinal) : Cardinal;{$ifdef fpc}inline;{$endif}
  384. var
  385. a, b, c, d : Byte;
  386. y : cardinal;
  387. begin
  388. d:=x and $FF;
  389. x:=x shr 8;
  390. c:=x and $FF;
  391. x:=x shr 8;
  392. b:=x and $FF;
  393. x:=x shr 8;
  394. a:= x and $FF;
  395. Result:=Sbox[0][a]+Sbox[1][b];
  396. Result:=Result xor Sbox[2][c];
  397. Result:=Result + Sbox[3][d];
  398. end;
  399. procedure TBlowFish.Encrypt(var Block : TBFBlock);
  400. var
  401. I : Integer;
  402. xl,xr,temp : Cardinal;
  403. begin
  404. Xl:= block[0];
  405. Xr:= block[1];
  406. for i:=0 to 15 do
  407. begin
  408. Xl:=Xl xor Pbox[i];
  409. Xr:= F(Xl) xor Xr;
  410. temp:= Xl;
  411. Xl:= Xr;
  412. Xr := temp;
  413. end;
  414. temp := Xl;
  415. Xl := Xr;
  416. Xr := temp;
  417. Xr := Xr xor Pbox[16];
  418. Xl := Xl xor Pbox[17];
  419. Block[0]:=Xl;
  420. Block[1]:=Xr;
  421. end;
  422. procedure TBlowFish.Decrypt(var Block : TBFBlock);
  423. var
  424. I : Integer;
  425. xl,xr,temp : Cardinal;
  426. begin
  427. Xl:= block[0];
  428. Xr:= block[1];
  429. for i:=17 downto 2 do
  430. begin
  431. Xl := Xl xor PBox[i];
  432. Xr := F(Xl) xor Xr;
  433. temp := Xl;
  434. Xl := Xr;
  435. Xr := temp;
  436. end;
  437. temp := Xl;
  438. Xl := Xr;
  439. Xr := temp;
  440. Xr := Xr xor Pbox[1];
  441. Xl := Xl xor Pbox[0];
  442. Block[0]:=Xl;
  443. Block[1]:=Xr;
  444. end;
  445. { ---------------------------------------------------------------------
  446. TBlowFishStream
  447. ---------------------------------------------------------------------}
  448. Constructor TBlowFishStream.Create(AKey : TBlowFishkey; AKeySize : Byte; Dest: TStream);
  449. begin
  450. inherited Create(Dest);
  451. FBF:=TBlowFish.Create(AKey,AKeySize);
  452. FBufPos:=0;
  453. FPos:=0;
  454. end;
  455. constructor TBlowFishStream.Create(const KeyPhrase: String; Dest: TStream);
  456. Var
  457. KLen : Integer;
  458. K : TBlowFishKey;
  459. begin
  460. If (KeyPhrase='') then
  461. Raise EBlowFishError.Create(SErrEmptyPassPhraseNotAllowed);
  462. KLen:=Length(KeyPhrase);
  463. If KLen>56 then
  464. KLen:=56;
  465. Move(KeyPhrase[1],K,Klen);
  466. Create(K,KLen,Dest);
  467. end;
  468. Destructor TBlowFishStream.Destroy;
  469. begin
  470. FreeAndNil(FBF);
  471. Inherited;
  472. end;
  473. { ---------------------------------------------------------------------
  474. TBlowFishEncryptStream
  475. ---------------------------------------------------------------------}
  476. Destructor TBlowFishEncryptStream.Destroy;
  477. begin
  478. Flush;
  479. Inherited Destroy;
  480. end;
  481. Procedure TBlowFishEncryptStream.Flush;
  482. begin
  483. If FBufPos>0 then
  484. begin
  485. // Fill with nulls
  486. FillChar(PChar(@FData)[FBufPos],SizeOf(FData)-FBufPos,#0);
  487. FBF.EnCrypt(FData);
  488. Source.Write(FData,SizeOf(FData));
  489. FBufPos := 0;
  490. end;
  491. end;
  492. function TBlowFishEncryptStream.Write(const Buffer; Count: Longint): Longint;
  493. Var
  494. mvsize : Longint;
  495. begin
  496. Result:=0;
  497. While Count>0 do
  498. begin
  499. MVsize:=Count;
  500. If Mvsize>SizeOf(Fdata)-FBufPos then
  501. mvsize:=SizeOf(FData)-FBufPos;
  502. Move(PChar(@Buffer)[Result],PChar(@FData)[FBufPos],MVSize);
  503. If FBufPos+mvSize=Sizeof(FData) then
  504. begin
  505. // Empty buffer.
  506. FBF.Encrypt(FData);
  507. // this will raise an exception if needed.
  508. Source.Writebuffer(FData,SizeOf(FData));
  509. FBufPos:=0;
  510. end
  511. else
  512. inc(FBufPos,mvsize);
  513. Dec(Count,MvSize);
  514. Inc(Result,mvSize);
  515. end;
  516. Inc(FPos,Result);
  517. end;
  518. function TBlowFishEncryptStream.Seek(Offset: Longint; Origin: Word): Longint;
  519. begin
  520. if (Offset = 0) and (Origin = soFromCurrent) then
  521. Result := FPos
  522. else
  523. Raise EBlowFishError.Create(SNoSeekAllowed);
  524. end;
  525. { ---------------------------------------------------------------------
  526. TBlowFishDecryptStream
  527. ---------------------------------------------------------------------}
  528. function TBlowFishDeCryptStream.Read(var Buffer; Count: Longint): Longint;
  529. Var
  530. mvsize : Longint;
  531. begin
  532. Result:=0;
  533. While Count>0 do
  534. begin
  535. // Empty existing buffer.
  536. If (FBufPos>0) then
  537. begin
  538. mvSize:=FBufPos;
  539. If MvSize>count then
  540. mvsize:=Count;
  541. Move(PChar(@FData)[0],PChar(@Buffer)[Result],MVSize);
  542. If ((Sizeof(FData)-MvSize)>0) then
  543. Move(PChar(@FData)[mvSize],PChar(@FData)[0],Sizeof(FData)-MvSize);
  544. Dec(Count,mvsize);
  545. Inc(Result,mvsize);
  546. FBufPos:=FBufPos-MvSize;
  547. end;
  548. // Fill buffer again if needed.
  549. If (Count>0) then
  550. Begin
  551. mvsize:=Source.Read(FData,SizeOf(FData));
  552. If mvsize>0 then
  553. begin
  554. If MvSize<SizeOf(FData) Then
  555. // Fill with nulls
  556. FillChar(PChar(@FData)[mvsize],SizeOf(FData)-mvsize,#0);
  557. FBF.Decrypt(FData);
  558. FBufPos:=SizeOf(FData);
  559. end
  560. else
  561. Count:=0; // No more data available from stream; st
  562. end;
  563. end;
  564. Inc(FPos,Result);
  565. end;
  566. function TBlowFishDeCryptStream.Seek(Offset: Longint; Origin: Word): Longint;
  567. Var Buffer : Array[0..1023] of byte;
  568. i : longint;
  569. begin
  570. // Fake seek if possible by reading and discarding bytes.
  571. If ((Offset>=0) and (Origin = soFromCurrent)) or
  572. ((Offset>FPos) and (Origin = soFromBeginning)) then
  573. begin
  574. For I:=1 to (Offset div SizeOf(Buffer)) do
  575. ReadBuffer(Buffer,SizeOf(Buffer));
  576. ReadBuffer(Buffer,Offset mod SizeOf(Buffer));
  577. Result:=FPos;
  578. end
  579. else
  580. Raise EBlowFishError.Create(SNoSeekAllowed);
  581. end;
  582. end.