home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume25 / crack / part03 < prev    next >
Text File  |  1991-11-03  |  43KB  |  1,247 lines

  1. Newsgroups: comp.sources.misc,alt.security
  2. From: aem@aberystwyth.ac.uk (Alec Muffett)
  3. Subject:  v25i007:  crack - The Password Cracker, version 4.0a, Part03/05
  4. Message-ID: <1991Nov3.231544.10268@sparky.imd.sterling.com>
  5. X-Md4-Signature: d19cdf7210b74f434b26da0b4f1aa413
  6. Date: Sun, 3 Nov 1991 23:15:44 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: aem@aber.ac.uk (Alec David Muffett)
  10. Posting-number: Volume 25, Issue 7
  11. Archive-name: crack/part03
  12. Environment: UNIX
  13. Supersedes: crack: Volume 23, Issue 1-5
  14.  
  15. #! /bin/sh
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 3 (of 5)."
  21. # Contents:  APPENDIX.4.0 Sources/crack-fcrypt.c
  22. # Wrapped by aem@aberda on Thu Oct 24 11:14:43 1991
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'APPENDIX.4.0' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'APPENDIX.4.0'\"
  26. else
  27. echo shar: Extracting \"'APPENDIX.4.0'\" \(16140 characters\)
  28. sed "s/^X//" >'APPENDIX.4.0' <<'END_OF_FILE'
  29. XAPPENDIX FILE FOR VERSION 4.0 of Crack.  By Alec Muffett, 7th Oct 1991
  30. X**********************************************************************
  31. XThis is the latest version of Crack, The Sensible Password Cracker.
  32. X
  33. XThere have been a LOT of changes since version 3.*, first and foremost,
  34. Xthere is NO DICTIONARY PREPROCESSOR.  This is part of a drive during
  35. Xre-writing the code to move as much as possible of the configuration
  36. Xgumph out of the central code and into the Scripts directory. 
  37. X
  38. XAll the manipulations which are carried out on the dictionary are
  39. Xcontrolled by external files, so that the user can configure the program
  40. Xto permute and unique the dictionary on the fly, saving vast amounts of
  41. Xfilestore for a small time tradeoff. 
  42. X
  43. XIf you really want to make a dictionary pass of capitalised reversed
  44. Xwords containing the letter "Q" with a semicolon appended, feel free!
  45. XThe rule is:-
  46. X                cr/Q$;
  47. X
  48. XThis is further detailed in the README file.  The extra flexibility
  49. Xgenerated is worth the slight loss in efficiency,
  50. X
  51. XOther changes in attitude and programming style: Crack is now written
  52. Xwith most of it's features hardwired in; eg: Feedback mode is no longer
  53. Xoptional, Crack output files ALWAYS print their guesses, and so on.
  54. X
  55. XThis is partly due to laziness, and partly due to the complexity of the
  56. Xcode.  It's simpler if I assume that users don't want to go around
  57. Xcrippling the code before running it.
  58. X
  59. XAlso, I assume that certin features are supplied with your c-compiler
  60. Xtoo.  You will need a qsort() function as well as a getopt() function to
  61. Xrun v4.0, but these are pretty common nowadays.  If not, complain to
  62. Xyour vendor or pull one from the public domain.
  63. X
  64. XAlso, I've tried (with a lot of external help: thanks to cip_maz) to get
  65. XCrack working on 16 bit machines.  It may work...  8-)
  66. X
  67. XCrack now can scan .plan/.project/.signature files for information... 
  68. XIt only checks the first 1Kb of each file...  I consider this to be
  69. Xenough, because, as I well know, some .plan files get a bit bigger than
  70. Xthat.  (If you don't know what I'm talking about, pull a copy of ASP
  71. Xfrom your local comp.sources.misc archive.  My big .plan is 2.6Mb)
  72. X
  73. XFinally, I'm providing with this version a "terms of usage" file, which
  74. Xdetails what I would like people to do or not do with my code.  I've
  75. Xworked bloody hard on this project, partly in hope that it will scare
  76. Xthe commercial world into doing things for unix security amongst the
  77. Xunix community.  Two BIG multinationals have already contacted me about
  78. Xthis code, but mostly because it's done horrible things to their
  79. Xinternal network security.  I'd like to see them implement something for
  80. Xthe users, too...
  81. X
  82. XI DO intend to keep Crack up to date with development work, but my
  83. Xfuture on the net is looking a little shaky at the moment.  Hang in
  84. Xthere - if you get no immediate reply on EMailing me, I'll get back to
  85. Xyou eventually.  It does seem that Crack v4.0 has gone just about as far
  86. Xas it can without being too silly or inefficient, so I am going to have
  87. Xto consider VERY CAREFULLY about where it goes from here on in. 
  88. X
  89. X            in peaceful paranoia,
  90. X                yours sincerely,
  91. X
  92. X                    alec muffett (with TWO T's !)
  93. X***********************************************************************
  94. XThere now follows any information that is still pertinent from previous
  95. XAPPENDIX files
  96. X***********************************************************************
  97. X
  98. XSeveral people have asked me why I don't write Crack so that it
  99. Xdistributes dictionaries over the network and hacks the same password
  100. Xfile on each machine, as opposed to spreading users over the network and
  101. Xusing the same dictionaries.
  102. X
  103. XThere are several reasons for this, which I will outline.
  104. X
  105. XThe reasoning that spreading the dictionaries over the network is faster
  106. Xis correct in the case of cracking the passwords of ONE user - it is
  107. Xmost efficient to run different dictionaries on him on several machines,
  108. Xand you will break his password eventually.
  109. X
  110. XScaling this by a factor of 'n' users causes problems.  Firstly, if a
  111. Xmachine guesses one persons password, it must inform all others on the
  112. Xnetwork not to waste time cracking him, but to get on with the other
  113. Xusers.  This is difficult and nasty.
  114. X
  115. XSecondly, it is not what Crack was designed to do.  The name "Crack" is
  116. Xactually a misnomer - Crack really ought to be called "Passwdcheck" or
  117. Xsomething similar, but such names lack sex appeal.
  118. X
  119. XCrack is not a program designed to break the password of every user in
  120. Xthe file.  Rather, it is designed to find weak passwords in the file, by
  121. Xattacking those sorts of bad passwords which are most likely to be used,
  122. Xin the order in which they would most easily be found (ie: are most
  123. Xlikely to be used by a moronic user).
  124. X
  125. XCrack is not designed to break user passwords; it is designed to break
  126. Xpassword files.  This is a subtle but important distinction.
  127. X
  128. XIf you want to break into a safe, you do not take a hammer at every bit
  129. Xof it in turn; instead, first you try some simple combinations, then you
  130. Xtry blowing the hinges off, then you get out an acetylene torch and go
  131. Xfor the bolt.  If that doesnt work, THEN you start on the walls.  You go
  132. Xfor the bits which are most likely to be weak first.
  133. X
  134. XConsider a password file with 'n' users in it.  Say that your ordinary,
  135. Xserial password cracker uses a dictionary of 1000 words, and tries each
  136. Xword 6 ways (upper/lower/mixed case, permuted with forwards/backwards)
  137. X
  138. XAlso consider that out of that 1000 users, only one (the last one) has a
  139. Xguessable password - "fred".
  140. X
  141. XAlso say that it takes time 'T' seconds to encrypt a word.
  142. X
  143. XIf you use the "try each user in turn" method, like the COPS password
  144. Xcracker, you will have to wait for a time:-
  145. X
  146. X    999 users * 1000 words * 6 ways * T = 5994000 T seconds
  147. X
  148. Xbefore you get to that last user.  Spreading this load around on a
  149. Xnetwork only alleviates the number of words to be searched (divides them
  150. Xby the number of machines you are working on).
  151. X
  152. XThus, if you use 10 machines, the machine which will guess "fred" will
  153. Xget to that last user in:-
  154. X
  155. X    999 * (1000 / 10) * 6 ways = 599400 T seconds.
  156. X
  157. XAlternatively you can try it the Crack way - "fred" is a word which
  158. Xappears in a forwards dictionary.  You will only wait:-
  159. X
  160. X    999 users * 1000 words * 1st way * T = 999000 T seconds
  161. X
  162. Xto get to that user.  Now split the users across 10 machines (for
  163. Xsimplicity, as outlined above):-
  164. X
  165. X    (999 / 10) users * 1000 words * 1st way = 99900 T seconds
  166. X
  167. XTo get to his password, in ONLY 17% of the time taken by networking
  168. Xusing the serial cracking method.  This is only a boundary case, but I
  169. Xhope I have illustrated the concept.
  170. X
  171. X********
  172. X
  173. XCrack has several other optimisations because of its structured password
  174. Xguesses.  The figures below are entirely empirical, but I reckon that
  175. Xthey're as good as any:
  176. X
  177. XThe first pass that Crack makes is over the user data user information
  178. Xgleaned from the users' password field.  In my test file, this gets
  179. Xabout 3% of the passwords (out of a total of 11% guessed).  This pass
  180. Xalso completes the quickest of all, working as it does from a very small
  181. Xamount of data, but one which is very frequently used for passwords.
  182. X
  183. XThe first sweep of the second pass, consisting of lowercase dictionary
  184. Xwords, gets about another 5% of the passwords.  This means that, for our
  185. X1150 users, we have now cracked a cumulative total of 91 accounts.  The
  186. Xlength of the first sweep depends on how much CPU and how many
  187. Xdictionaries I supply, but using the Ultrix /usr/dict/words and my
  188. Xbad_pws.dat, over 4 CPUs, it doesn't take much more that a couple of
  189. Xhours.
  190. X
  191. XFor the further sweeps, the percentages cracked per sweep tail off, 2%,
  192. X1%, 0.5%...  But they are the people with fairly exotic passwords, and
  193. Xit's only common sense that that they will take some time to crack.
  194. X
  195. X********
  196. X
  197. XThere is one more major optimisation that I haven't mentioned.  Because
  198. Xof the way the UNIX crypt() algorithm works, each encryption is "salted"
  199. Xwith a two letter sequence which is stored as the first two characters
  200. Xof the encrypted password.  This salting means that the word "fred" can
  201. Xbe encrypted and appear in a password file in (literally) thousands of
  202. Xdifferent ways - so long as each encryption has a different salt.
  203. X
  204. XHence, it makes sense to do things in this manner:
  205. X
  206. X1) sort and group the input data by encryption salt.
  207. X2) for each different groups' encryption salt
  208. X    * get a dictionary word
  209. X    * encrypt it using that salt (This is the time consuming bit)
  210. X    * compare the encryption with each member of the group with that salt
  211. X    * if it matches, you have guessed that users password.
  212. X
  213. XThis knocks (empirical guesswork time again) up to one third of the
  214. Xdictionary encryptions off - thus saving you 0.3 of the time all the
  215. Xdictionary sweeps would ordinarily take.  You can work out this figure
  216. Xyourself: Crack gives this statistic when it says
  217. X
  218. X    pwc: Loaded 'n' password entries into 'm' salted lines.
  219. X
  220. Xso you can work out the percentage of users who have the same salt:-
  221. X
  222. X            x = (m / n) * 100
  223. X
  224. Xand hence the percentage of encryption time that you save = (100 - x).
  225. X
  226. X********
  227. X
  228. XI was listening to the REM album 'Green' on the way back from the
  229. XCropredy folk festival, whilst thinking over things to do to Crack, and
  230. XI was struck (not for the first time) by the words of the first verse to
  231. X'World Leader Pretend':-
  232. X
  233. X    I sit at my table, and wage war upon myself.
  234. X    It seems like it's all, it's all for nothing.
  235. X    I know the barricades, and I know the mortar in the wall
  236. X    I recognise the weapons, I use them well.
  237. X
  238. X    This is my mistake, let me make it good,
  239. X    I raised the wall, and I will be the one to knock it down...
  240. X
  241. X- writing password cracking programs gets to you after a bit.
  242. X
  243. X********
  244. X
  245. XSome people have asked me how to generate safe passwords.  This, sadly,
  246. Xhas become a religious issue, and there are now, on USENET, several
  247. Xvociferous "password geeks" who will say "my method is the best", in the
  248. Xsame way that some mathematicians will try to compare so-called "random
  249. Xnumber generating algorithms".  Such statements are pointless.  I'm
  250. Xsorry for adding to the confusion, but I must say that I think they are
  251. Xwrong.
  252. X
  253. XOkay, so I am a security fatalist and a security philosopher, but I am
  254. Xnot going to give and hard and fast answers; rather, I'd like to make
  255. Xsome points and recommendations to the people out there.  Security isn't
  256. Xa tangible thing, it is applied psychology.
  257. X
  258. XThe whole point of a password is to prevent people accessing your
  259. Xsystem, getting into it from outside.  Once someone is inside your
  260. Xsystem, assuming that they have the relevant knowledge of your O/S, it
  261. Xis safest to assume that anyone can get to be 'superuser'.  Your only
  262. Xsecurity once someone is on your system is called "security by
  263. Xobscurity".  If your user has sufficient knowledge, you've "had it".
  264. X
  265. XThe question isn't "How secure can my system be made?".
  266. X
  267. XThe question really should be, "How much do I care, how much can I trust?".
  268. X
  269. XA system can be perfectly secure without any passwords at all, so long
  270. Xas it is in an environment of people who recognise its purpose and
  271. Xdepend on it.  I say this after having had acounts on several 'public'
  272. Xmachines, which could have been taken to bits by any competent Unix
  273. Xperson, but were largely safe - because when someone worked out who did
  274. Xanything nasty, the culprit was ostracised from the community.  There
  275. X_is_ a caveat to this, however.
  276. X
  277. XThe problem is the sort of people who go around the world 'collecting'
  278. Xcomputer accounts and breaking machines, those who have either a
  279. Xchildish mentality or an ulterior motive.
  280. X
  281. XThe former are like the little boys who go around breaking windows and
  282. Xvandalising things 'for kicks'.  They are the ones who see every
  283. Xpassword file as a "NO ENTRY" sign, and therefore, driven by what they
  284. Xthink is anarchy and fun, they break in and smash the place up.  Tell
  285. Xthem that they are behaving like children, and they will behave moreso.
  286. X
  287. XThe latter are driven by personal motives or money.  Their reasons are
  288. Xtoo complex for me to analyse here.
  289. X
  290. XThe 'babyish' hackers need a lesson (which I hope that eventually they
  291. Xlearn) that true anarchy is for the general good, and is best achieved
  292. Xby fiat amongst the community.  USENET is a good example - there is a
  293. Xlot of petty bickering and arguing, but an incredible amount of good
  294. Xcomes out of it.  It is anarchy that the old greek philosophers would
  295. Xhave approved of.
  296. X
  297. XWhat I am trying to say is that, when I say that if someone gets into
  298. Xyour system, you've "had it", you should consider whether there is
  299. Xanything to have "had" in the first place.  There is no point in getting
  300. Xyourself paranoid over security - if you do, you'll lose out.  Don't be
  301. Xtoo paranoid.  Be SENSIBLE instead, and secure your system according to
  302. Xit's needs, and not according to some 'holy bible' of absolute security.
  303. X
  304. XIf someone gets into your system, you find out how they did it, patch
  305. Xthe hole, check for back doors, brush yourself off, and start again.
  306. XIt's not the end of the world.
  307. X
  308. XWhat this statement doesn't address (yet) is the needs of system
  309. Xmanagers who have a REAL need for security - be it corporate data or
  310. Xresearch work - on their system.  As I have said before, most O/S's have
  311. Xgaping holes in them that cannot be entirely filled, and so the crackers
  312. Xmust be stopped on the doorstep.  At the password login.
  313. X
  314. XPeople who say that they have a way of generating safe passwords are
  315. Xmisinformed, IMHO.  Saying that the password "wyufwqpl" is secure is as
  316. Xmeaningful as saying that the number "4" is random.  Password security,
  317. Xlike any other form of computer security, is not absolute, but should
  318. Xbe taken in context.
  319. X
  320. XYou can't say that a certain method will provide secure, random
  321. Xpasswords, because, in defining an algorithm to create these passwords,
  322. Xyou will use only a subset of all the possible passwords that could ever
  323. Xexist.  You have shrunk the 'search space' for the passwords.
  324. X
  325. XSomeone merely has to write a password cracker which will search this
  326. Xsmall subset of passwords, in order to break your system.  Passwords
  327. Xgenerated by any algorithm, human or computer based, are merly
  328. Xpseudo-secure, in the same way that numbers can be pseudo-random.  For
  329. Xillustration of this aspect of password security, read the document
  330. X"Password Security, A Case History" by Morris and Thompson.
  331. X
  332. XThere is an incredibly large set of possible passwords in the world, and
  333. Xthe best approach toward choosing a password is not to try to find a way
  334. Xto generate 'secure' passwords - there are no such things - but rather
  335. Xyou should learn to choose passwords which are not easily searched for.
  336. XPasswords which are out of the 'search space' of most password crackers
  337. Xlike 'Crack'.
  338. X
  339. XRead the Crack documentation.  See what sort of things other programs
  340. Xlike Crack would search for.  Think of some yourself.  I am not going to
  341. Xspecifically mention methods, you should really work something out for
  342. Xyourself.
  343. X
  344. XAt the bottom line, the password "fred" is just as secure (random) as
  345. Xthe password "blurflpox"; the only problem is that "fred" is in a more
  346. Xeasily searched part of the "password space".
  347. X
  348. XBoth of these passwords are more easily found than "Dxk&2+15^N" however.
  349. XNow you must ask yourself if you can cope with remembering "Dxk&2+15^N".
  350. X
  351. X8-)
  352. X
  353. X********
  354. X
  355. XI'd like to thank Chris Samuel & Piercarlo (Peter) Grandi for all their
  356. Xhelp in beta-testing early versions of Crack, and in Peter's case
  357. Xespecially, for dropping me into the deep end of troff.  Die, you
  358. Xbastard.  8->
  359. X
  360. XI'd also like to thank Chris Myers, Randal Schwartz, Chris Lewis,
  361. XM.Maclaren@bath, and Brian Tompsett (bct@uk.ac.hull.cs), for pointing me
  362. Xto the now famous v3.2 bug, and for numerous suggestions and patches,
  363. Xnot to mention the enormous amount of debugging information he's sent me
  364. Xabout Crack v3.3.  To him should go the prize for "Most Vociferous Beta
  365. XTester". 
  366. X
  367. XAnd finally, to my girlfriend Gilly, for her occasional large doses of
  368. Xsanity.  8-)
  369. X                        - alec
  370. X--
  371. XINET: aem@aber.ac.uk      JANET: aem@uk.ac.aber      BITNET: aem%aber@ukacrl
  372. XUUCP: ...!mcsun!ukc!aber!aem         ARPA: aem%uk.ac.aber@nsfnet-relay.ac.uk
  373. XSNAIL: Alec Muffett, Computer Unit, Llandinam UCW, Aberystwyth, UK, SY23 3DB
  374. X
  375. END_OF_FILE
  376. if test 16140 -ne `wc -c <'APPENDIX.4.0'`; then
  377.     echo shar: \"'APPENDIX.4.0'\" unpacked with wrong size!
  378. fi
  379. # end of 'APPENDIX.4.0'
  380. fi
  381. if test -f 'Sources/crack-fcrypt.c' -a "${1}" != "-c" ; then 
  382.   echo shar: Will not clobber existing file \"'Sources/crack-fcrypt.c'\"
  383. else
  384. echo shar: Extracting \"'Sources/crack-fcrypt.c'\" \(22754 characters\)
  385. sed "s/^X//" >'Sources/crack-fcrypt.c' <<'END_OF_FILE'
  386. X/*
  387. X * This program is copyright Alec Muffett 1991 except for some portions of
  388. X * code in "crack-fcrypt.c" which are copyright Robert Baldwin, Icarus
  389. X * Sparry and Alec Muffett.  The author(s) disclaims all responsibility or
  390. X * liability with respect to it's usage or its effect upon hardware or
  391. X * computer systems, and maintain copyright as set out in the "LICENCE"
  392. X * document which accompanies distributions of Crack v4.0 and upwards. 
  393. X */
  394. X
  395. X/*
  396. X * Misc defs for the fast password transform optimisations.
  397. X */
  398. X
  399. X#include "crack.h"
  400. X
  401. X/*
  402. X * Data segment gathered into one place, try to keep this stuff long aligned
  403. X * - AEM
  404. X */
  405. X
  406. Xstatic char iobuf[16];
  407. Xstatic obpb1 crypt_block[72];    /* 72 is next multiple of 8 bytes after 66 */
  408. Xstatic sbpb24 KS[32];
  409. Xstatic sbpb24 S0H[64], S1H[64], S2H[64], S3H[64];
  410. Xstatic sbpb24 S4H[64], S5H[64], S6H[64], S7H[64];
  411. Xstatic sbpb24 S0L[64], S1L[64], S2L[64], S3L[64];
  412. Xstatic sbpb24 S4L[64], S5L[64], S6L[64], S7L[64];
  413. Xstatic sbpb24 out96[4];
  414. X
  415. X/*
  416. X * Start of the real thing
  417. X */
  418. X
  419. Xvoid
  420. Xfsetkey ()
  421. X{
  422. X    /*
  423. X     * This used to be utterly horrendous. It still is, but it's much, much,
  424. X     * smaller... (and quite a bit faster...) - AEM
  425. X     */
  426. X    static unsb KeyToKS[] =
  427. X    {
  428. X    9, 50, 33, 59, 48, 16, 32, 56, 1, 8, 18, 41, 2, 34, 25, 24,
  429. X    43, 57, 58, 0, 35, 26, 17, 40, 21, 27, 38, 53, 36, 3, 46, 29,
  430. X    4, 52, 22, 28, 60, 20, 37, 62, 14, 19, 44, 13, 12, 61, 54, 30,
  431. X    1, 42, 25, 51, 40, 8, 24, 48, 58, 0, 10, 33, 59, 26, 17, 16,
  432. X    35, 49, 50, 57, 56, 18, 9, 32, 13, 19, 30, 45, 28, 62, 38, 21,
  433. X    27, 44, 14, 20, 52, 12, 29, 54, 6, 11, 36, 5, 4, 53, 46, 22,
  434. X    50, 26, 9, 35, 24, 57, 8, 32, 42, 49, 59, 17, 43, 10, 1, 0,
  435. X    48, 33, 34, 41, 40, 2, 58, 16, 60, 3, 14, 29, 12, 46, 22, 5,
  436. X    11, 28, 61, 4, 36, 27, 13, 38, 53, 62, 20, 52, 19, 37, 30, 6,
  437. X    34, 10, 58, 48, 8, 41, 57, 16, 26, 33, 43, 1, 56, 59, 50, 49,
  438. X    32, 17, 18, 25, 24, 51, 42, 0, 44, 54, 61, 13, 27, 30, 6, 52,
  439. X    62, 12, 45, 19, 20, 11, 60, 22, 37, 46, 4, 36, 3, 21, 14, 53,
  440. X    18, 59, 42, 32, 57, 25, 41, 0, 10, 17, 56, 50, 40, 43, 34, 33,
  441. X    16, 1, 2, 9, 8, 35, 26, 49, 28, 38, 45, 60, 11, 14, 53, 36,
  442. X    46, 27, 29, 3, 4, 62, 44, 6, 21, 30, 19, 20, 54, 5, 61, 37,
  443. X    2, 43, 26, 16, 41, 9, 25, 49, 59, 1, 40, 34, 24, 56, 18, 17,
  444. X    0, 50, 51, 58, 57, 48, 10, 33, 12, 22, 29, 44, 62, 61, 37, 20,
  445. X    30, 11, 13, 54, 19, 46, 28, 53, 5, 14, 3, 4, 38, 52, 45, 21,
  446. X    51, 56, 10, 0, 25, 58, 9, 33, 43, 50, 24, 18, 8, 40, 2, 1,
  447. X    49, 34, 35, 42, 41, 32, 59, 17, 27, 6, 13, 28, 46, 45, 21, 4,
  448. X    14, 62, 60, 38, 3, 30, 12, 37, 52, 61, 54, 19, 22, 36, 29, 5,
  449. X    35, 40, 59, 49, 9, 42, 58, 17, 56, 34, 8, 2, 57, 24, 51, 50,
  450. X    33, 18, 48, 26, 25, 16, 43, 1, 11, 53, 60, 12, 30, 29, 5, 19,
  451. X    61, 46, 44, 22, 54, 14, 27, 21, 36, 45, 38, 3, 6, 20, 13, 52,
  452. X    56, 32, 51, 41, 1, 34, 50, 9, 48, 26, 0, 59, 49, 16, 43, 42,
  453. X    25, 10, 40, 18, 17, 8, 35, 58, 3, 45, 52, 4, 22, 21, 60, 11,
  454. X    53, 38, 36, 14, 46, 6, 19, 13, 28, 37, 30, 62, 61, 12, 5, 44,
  455. X    40, 16, 35, 25, 50, 18, 34, 58, 32, 10, 49, 43, 33, 0, 56, 26,
  456. X    9, 59, 24, 2, 1, 57, 48, 42, 54, 29, 36, 19, 6, 5, 44, 62,
  457. X    37, 22, 20, 61, 30, 53, 3, 60, 12, 21, 14, 46, 45, 27, 52, 28,
  458. X    24, 0, 48, 9, 34, 2, 18, 42, 16, 59, 33, 56, 17, 49, 40, 10,
  459. X    58, 43, 8, 51, 50, 41, 32, 26, 38, 13, 20, 3, 53, 52, 28, 46,
  460. X    21, 6, 4, 45, 14, 37, 54, 44, 27, 5, 61, 30, 29, 11, 36, 12,
  461. X    8, 49, 32, 58, 18, 51, 2, 26, 0, 43, 17, 40, 1, 33, 24, 59,
  462. X    42, 56, 57, 35, 34, 25, 16, 10, 22, 60, 4, 54, 37, 36, 12, 30,
  463. X    5, 53, 19, 29, 61, 21, 38, 28, 11, 52, 45, 14, 13, 62, 20, 27,
  464. X    57, 33, 16, 42, 2, 35, 51, 10, 49, 56, 1, 24, 50, 17, 8, 43,
  465. X    26, 40, 41, 48, 18, 9, 0, 59, 6, 44, 19, 38, 21, 20, 27, 14,
  466. X    52, 37, 3, 13, 45, 5, 22, 12, 62, 36, 29, 61, 60, 46, 4, 11,
  467. X    41, 17, 0, 26, 51, 48, 35, 59, 33, 40, 50, 8, 34, 1, 57, 56,
  468. X    10, 24, 25, 32, 2, 58, 49, 43, 53, 28, 3, 22, 5, 4, 11, 61,
  469. X    36, 21, 54, 60, 29, 52, 6, 27, 46, 20, 13, 45, 44, 30, 19, 62,
  470. X    25, 1, 49, 10, 35, 32, 48, 43, 17, 24, 34, 57, 18, 50, 41, 40,
  471. X    59, 8, 9, 16, 51, 42, 33, 56, 37, 12, 54, 6, 52, 19, 62, 45,
  472. X    20, 5, 38, 44, 13, 36, 53, 11, 30, 4, 60, 29, 28, 14, 3, 46,
  473. X    17, 58, 41, 2, 56, 24, 40, 35, 9, 16, 26, 49, 10, 42, 33, 32,
  474. X    51, 0, 1, 8, 43, 34, 25, 48, 29, 4, 46, 61, 44, 11, 54, 37,
  475. X    12, 60, 30, 36, 5, 28, 45, 3, 22, 27, 52, 21, 20, 6, 62, 38
  476. X    };
  477. X
  478. X    reg int i;
  479. X    reg int j;
  480. X    reg unsigned long r;
  481. X    reg unsb *k;
  482. X
  483. X    k = KeyToKS;
  484. X
  485. X    for (i = 0; i < 32; i++)
  486. X    {
  487. X    /* 16-bit tweaks suggested by cip_maz@fb6tcp.physik.uni-paderborn.de */
  488. X    /* inlining speedup tweak suggested by tahorsley@csd.harris.com */
  489. X    /* (strange addition compensates missing TF_TO_SIXBIT) */
  490. X    r = (unsigned long) crypt_block[*(k++)];
  491. X    r |= (unsigned long) crypt_block[*(k++)] << 1;
  492. X    r |= (unsigned long) crypt_block[*(k++)] << 2;
  493. X    r |= (unsigned long) crypt_block[*(k++)] << 3;
  494. X    r |= (unsigned long) crypt_block[*(k++)] << 4;
  495. X    r |= (unsigned long) crypt_block[*(k++)] << 5;
  496. X    r |= (unsigned long) crypt_block[*(k++)] << (2 + 6);
  497. X    r |= (unsigned long) crypt_block[*(k++)] << (2 + 7);
  498. X    r |= (unsigned long) crypt_block[*(k++)] << (2 + 8);
  499. X    r |= (unsigned long) crypt_block[*(k++)] << (2 + 9);
  500. X    r |= (unsigned long) crypt_block[*(k++)] << (2 + 10);
  501. X    r |= (unsigned long) crypt_block[*(k++)] << (2 + 11);
  502. X    r |= (unsigned long) crypt_block[*(k++)] << (4 + 12);
  503. X    r |= (unsigned long) crypt_block[*(k++)] << (4 + 13);
  504. X    r |= (unsigned long) crypt_block[*(k++)] << (4 + 14);
  505. X    r |= (unsigned long) crypt_block[*(k++)] << (4 + 15);
  506. X    r |= (unsigned long) crypt_block[*(k++)] << (4 + 16);
  507. X    r |= (unsigned long) crypt_block[*(k++)] << (4 + 17);
  508. X    r |= (unsigned long) crypt_block[*(k++)] << (6 + 18);
  509. X    r |= (unsigned long) crypt_block[*(k++)] << (6 + 19);
  510. X    r |= (unsigned long) crypt_block[*(k++)] << (6 + 20);
  511. X    r |= (unsigned long) crypt_block[*(k++)] << (6 + 21);
  512. X    r |= (unsigned long) crypt_block[*(k++)] << (6 + 22);
  513. X    r |= (unsigned long) crypt_block[*(k++)] << (6 + 23);
  514. X    KS[i] = r;
  515. X    }
  516. X}
  517. X
  518. Xvoid
  519. XXForm (saltvalue)
  520. X    sbpb24 saltvalue;
  521. X{
  522. X#ifdef BIG_ENDIAN        /* Icarus Sparry, Bath - mod AEM */
  523. X#define STEP --
  524. X#define START &sdata.c[7]
  525. X#define Dl sdata.b[1]
  526. X#define Dh sdata.b[0]
  527. X#else                /* LITTLE_ENDIAN */
  528. X#define STEP ++
  529. X#define START &sdata.c[0]
  530. X#define Dl sdata.b[0]
  531. X#define Dh sdata.b[1]
  532. X#endif
  533. X    union SDATA sdata;
  534. X    reg sbpb24 Rl;
  535. X    reg sbpb24 Rh;
  536. X    reg sbpb24 Ll;
  537. X    reg sbpb24 Lh;
  538. X    reg sbpb6 *dp;
  539. X    int loop;
  540. X    int kloop;
  541. X    sbpb24 *kp;
  542. X    reg sbpb24 k;
  543. X#ifdef FDES_8BYTE
  544. X    reg sbpb24 tmpi;
  545. X#endif    /* FDES_8BYTE */
  546. X
  547. X    Ll = Lh = Rl = Rh = 0;
  548. X
  549. X    for (loop = 25; loop--; /* nothing */ )
  550. X    {
  551. X    kp = KS;
  552. X    for (kloop = 8; kloop--; /* nothing */ )
  553. X    {
  554. X        k = (Rl ^ Rh) & saltvalue;
  555. X#ifndef FDES_8BYTE
  556. X        Dl = (k ^ Rl ^ *kp++) << SIZEFIX;
  557. X        Dh = (k ^ Rh ^ *kp++) << SIZEFIX;
  558. X#else
  559. X        /* hack to make things work better - matthew kaufman */
  560. X        /* I haven't tried any of this - I don't have a cray... AEM */
  561. X        tmpi = (k ^ Rl ^ *kp++);
  562. X        sdata.c[3] = (tmpi >> 24) & 0x00ff;
  563. X        sdata.c[2] = (tmpi >> 16) & 0x00ff;
  564. X        sdata.c[1] = (tmpi >> 8) & 0x00ff;
  565. X        sdata.c[0] = (tmpi) & 0x00ff;
  566. X        tmpi = (k ^ Rh ^ *kp++);
  567. X        sdata.c[7] = (tmpi >> 24) & 0x00ff;
  568. X        sdata.c[6] = (tmpi >> 16) & 0x00ff;
  569. X        sdata.c[5] = (tmpi >> 8) & 0x00ff;
  570. X        sdata.c[4] = (tmpi) & 0x00ff;
  571. X#endif    /* FDES_8BYTE */
  572. X
  573. X        dp = START;
  574. X        Lh ^= INDIRECT (S0H, *dp);
  575. X        Ll ^= INDIRECT (S0L, *dp STEP);
  576. X        Lh ^= INDIRECT (S1H, *dp);
  577. X        Ll ^= INDIRECT (S1L, *dp STEP);
  578. X        Lh ^= INDIRECT (S2H, *dp);
  579. X        Ll ^= INDIRECT (S2L, *dp STEP);
  580. X        Lh ^= INDIRECT (S3H, *dp);
  581. X        Ll ^= INDIRECT (S3L, *dp STEP);
  582. X        Lh ^= INDIRECT (S4H, *dp);
  583. X        Ll ^= INDIRECT (S4L, *dp STEP);
  584. X        Lh ^= INDIRECT (S5H, *dp);
  585. X        Ll ^= INDIRECT (S5L, *dp STEP);
  586. X        Lh ^= INDIRECT (S6H, *dp);
  587. X        Ll ^= INDIRECT (S6L, *dp STEP);
  588. X        Lh ^= INDIRECT (S7H, *dp);
  589. X        Ll ^= INDIRECT (S7L, *dp STEP);
  590. X
  591. X        k = (Ll ^ Lh) & saltvalue;
  592. X#ifndef FDES_8BYTE
  593. X        Dl = (k ^ Ll ^ *kp++) << SIZEFIX;
  594. X        Dh = (k ^ Lh ^ *kp++) << SIZEFIX;
  595. X#else
  596. X        tmpi = (k ^ Ll ^ *kp++);
  597. X        sdata.c[3] = (tmpi >> 24) & 0x00ff;
  598. X        sdata.c[2] = (tmpi >> 16) & 0x00ff;
  599. X        sdata.c[1] = (tmpi >> 8) & 0x00ff;
  600. X        sdata.c[0] = (tmpi) & 0x00ff;
  601. X        tmpi = (k ^ Lh ^ *kp++);
  602. X        sdata.c[7] = (tmpi >> 24) & 0x00ff;
  603. X        sdata.c[6] = (tmpi >> 16) & 0x00ff;
  604. X        sdata.c[5] = (tmpi >> 8) & 0x00ff;
  605. X        sdata.c[4] = (tmpi) & 0x00ff;
  606. X#endif    /* FDES_8BYTE */
  607. X
  608. X        dp = START;
  609. X        Rh ^= INDIRECT (S0H, *dp);
  610. X        Rl ^= INDIRECT (S0L, *dp STEP);
  611. X        Rh ^= INDIRECT (S1H, *dp);
  612. X        Rl ^= INDIRECT (S1L, *dp STEP);
  613. X        Rh ^= INDIRECT (S2H, *dp);
  614. X        Rl ^= INDIRECT (S2L, *dp STEP);
  615. X        Rh ^= INDIRECT (S3H, *dp);
  616. X        Rl ^= INDIRECT (S3L, *dp STEP);
  617. X        Rh ^= INDIRECT (S4H, *dp);
  618. X        Rl ^= INDIRECT (S4L, *dp STEP);
  619. X        Rh ^= INDIRECT (S5H, *dp);
  620. X        Rl ^= INDIRECT (S5L, *dp STEP);
  621. X        Rh ^= INDIRECT (S6H, *dp);
  622. X        Rl ^= INDIRECT (S6L, *dp STEP);
  623. X        Rh ^= INDIRECT (S7H, *dp);
  624. X        Rl ^= INDIRECT (S7L, *dp STEP);
  625. X    }
  626. X
  627. X    Ll ^= Rl;
  628. X    Lh ^= Rh;
  629. X    Rl ^= Ll;
  630. X    Rh ^= Lh;
  631. X    Ll ^= Rl;
  632. X    Lh ^= Rh;
  633. X    }
  634. X
  635. X    /*
  636. X     * for reasons that I cannot explain, if I insert the contents of the
  637. X     * UnXForm function right HERE, making the tweaks as necessary to avoid
  638. X     * using out96[] to pass data, I LOSE 30% of my speed.  I don't know why.
  639. X     * Hence, I continue to use out96[]...
  640. X     */
  641. X    {
  642. X    reg sbpb24 *qp;
  643. X    qp = out96;
  644. X    *qp++ = Ll;
  645. X    *qp++ = Lh;
  646. X    *qp++ = Rl;
  647. X    *qp++ = Rh;
  648. X    }
  649. X}
  650. X
  651. Xvoid
  652. XUnXForm ()
  653. X{
  654. X    reg sbpb24 Rl;
  655. X    reg sbpb24 Rh;
  656. X    reg sbpb24 Ll;
  657. X    reg sbpb24 Lh;
  658. X    reg obpb1 *ptr;
  659. X    reg long int mask;
  660. X    register long int *lip;
  661. X
  662. X    Ll = SIXBIT_TO_TF (out96[0]);
  663. X    Lh = SIXBIT_TO_TF (out96[1]);
  664. X    Rl = SIXBIT_TO_TF (out96[2]);
  665. X    Rh = SIXBIT_TO_TF (out96[3]);
  666. X
  667. X#ifdef BUILTIN_CLEAR
  668. X    lip = (long int *) crypt_block;
  669. X    for (mask = (sizeof (crypt_block) / sizeof (long int)); mask--; /* - */ )
  670. X    {
  671. X    *(lip++) = 0L;
  672. X    }
  673. X#else                /* BUILTIN_CLEAR */
  674. X    bzero (crypt_block, 66);
  675. X#endif                /* BUILTIN_CLEAR */
  676. X
  677. X    ptr = crypt_block;
  678. X    mask = 0x000400L;
  679. X    if (Rl & mask)
  680. X    *ptr = 0x01;
  681. X    ptr++;
  682. X    if (Ll & mask)
  683. X    *ptr = 0x01;
  684. X    ptr++;
  685. X    mask = 0x400000L;
  686. X    if (Rl & mask)
  687. X    *ptr = 0x01;
  688. X    ptr++;
  689. X    if (Ll & mask)
  690. X    *ptr = 0x01;
  691. X    ptr++;
  692. X    mask = 0x000400L;
  693. X    if (Rh & mask)
  694. X    *ptr = 0x01;
  695. X    ptr++;
  696. X    if (Lh & mask)
  697. X    *ptr = 0x01;
  698. X    ptr++;
  699. X    mask = 0x400000L;
  700. X    if (Rh & mask)
  701. X    *ptr = 0x01;
  702. X    ptr++;
  703. X    if (Lh & mask)
  704. X    *ptr = 0x01;
  705. X    ptr++;
  706. X    mask = 0x000200L;
  707. X    if (Rl & mask)
  708. X    *ptr = 0x01;
  709. X    ptr++;
  710. X    if (Ll & mask)
  711. X    *ptr = 0x01;
  712. X    ptr++;
  713. X    mask = 0x200000L;
  714. X    if (Rl & mask)
  715. X    *ptr = 0x01;
  716. X    ptr++;
  717. X    if (Ll & mask)
  718. X    *ptr = 0x01;
  719. X    ptr++;
  720. X    mask = 0x000200L;
  721. X    if (Rh & mask)
  722. X    *ptr = 0x01;
  723. X    ptr++;
  724. X    if (Lh & mask)
  725. X    *ptr = 0x01;
  726. X    ptr++;
  727. X    mask = 0x200000L;
  728. X    if (Rh & mask)
  729. X    *ptr = 0x01;
  730. X    ptr++;
  731. X    if (Lh & mask)
  732. X    *ptr = 0x01;
  733. X    ptr++;
  734. X    mask = 0x000100L;
  735. X    if (Rl & mask)
  736. X    *ptr = 0x01;
  737. X    ptr++;
  738. X    if (Ll & mask)
  739. X    *ptr = 0x01;
  740. X    ptr++;
  741. X    mask = 0x100000L;
  742. X    if (Rl & mask)
  743. X    *ptr = 0x01;
  744. X    ptr++;
  745. X    if (Ll & mask)
  746. X    *ptr = 0x01;
  747. X    ptr++;
  748. X    mask = 0x000100L;
  749. X    if (Rh & mask)
  750. X    *ptr = 0x01;
  751. X    ptr++;
  752. X    if (Lh & mask)
  753. X    *ptr = 0x01;
  754. X    ptr++;
  755. X    mask = 0x100000L;
  756. X    if (Rh & mask)
  757. X    *ptr = 0x01;
  758. X    ptr++;
  759. X    if (Lh & mask)
  760. X    *ptr = 0x01;
  761. X    ptr++;
  762. X    mask = 0x000080L;
  763. X    if (Rl & mask)
  764. X    *ptr = 0x01;
  765. X    ptr++;
  766. X    if (Ll & mask)
  767. X    *ptr = 0x01;
  768. X    ptr++;
  769. X    mask = 0x080000L;
  770. X    if (Rl & mask)
  771. X    *ptr = 0x01;
  772. X    ptr++;
  773. X    if (Ll & mask)
  774. X    *ptr = 0x01;
  775. X    ptr++;
  776. X    mask = 0x000080L;
  777. X    if (Rh & mask)
  778. X    *ptr = 0x01;
  779. X    ptr++;
  780. X    if (Lh & mask)
  781. X    *ptr = 0x01;
  782. X    ptr++;
  783. X    mask = 0x080000L;
  784. X    if (Rh & mask)
  785. X    *ptr = 0x01;
  786. X    ptr++;
  787. X    if (Lh & mask)
  788. X    *ptr = 0x01;
  789. X    ptr++;
  790. X    mask = 0x000010L;
  791. X    if (Rl & mask)
  792. X    *ptr = 0x01;
  793. X    ptr++;
  794. X    if (Ll & mask)
  795. X    *ptr = 0x01;
  796. X    ptr++;
  797. X    mask = 0x010000L;
  798. X    if (Rl & mask)
  799. X    *ptr = 0x01;
  800. X    ptr++;
  801. X    if (Ll & mask)
  802. X    *ptr = 0x01;
  803. X    ptr++;
  804. X    mask = 0x000010L;
  805. X    if (Rh & mask)
  806. X    *ptr = 0x01;
  807. X    ptr++;
  808. X    if (Lh & mask)
  809. X    *ptr = 0x01;
  810. X    ptr++;
  811. X    mask = 0x010000L;
  812. X    if (Rh & mask)
  813. X    *ptr = 0x01;
  814. X    ptr++;
  815. X    if (Lh & mask)
  816. X    *ptr = 0x01;
  817. X    ptr++;
  818. X    mask = 0x000008L;
  819. X    if (Rl & mask)
  820. X    *ptr = 0x01;
  821. X    ptr++;
  822. X    if (Ll & mask)
  823. X    *ptr = 0x01;
  824. X    ptr++;
  825. X    mask = 0x008000L;
  826. X    if (Rl & mask)
  827. X    *ptr = 0x01;
  828. X    ptr++;
  829. X    if (Ll & mask)
  830. X    *ptr = 0x01;
  831. X    ptr++;
  832. X    mask = 0x000008L;
  833. X    if (Rh & mask)
  834. X    *ptr = 0x01;
  835. X    ptr++;
  836. X    if (Lh & mask)
  837. X    *ptr = 0x01;
  838. X    ptr++;
  839. X    mask = 0x008000L;
  840. X    if (Rh & mask)
  841. X    *ptr = 0x01;
  842. X    ptr++;
  843. X    if (Lh & mask)
  844. X    *ptr = 0x01;
  845. X    ptr++;
  846. X    mask = 0x000004L;
  847. X    if (Rl & mask)
  848. X    *ptr = 0x01;
  849. X    ptr++;
  850. X    if (Ll & mask)
  851. X    *ptr = 0x01;
  852. X    ptr++;
  853. X    mask = 0x004000L;
  854. X    if (Rl & mask)
  855. X    *ptr = 0x01;
  856. X    ptr++;
  857. X    if (Ll & mask)
  858. X    *ptr = 0x01;
  859. X    ptr++;
  860. X    mask = 0x000004L;
  861. X    if (Rh & mask)
  862. X    *ptr = 0x01;
  863. X    ptr++;
  864. X    if (Lh & mask)
  865. X    *ptr = 0x01;
  866. X    ptr++;
  867. X    mask = 0x004000L;
  868. X    if (Rh & mask)
  869. X    *ptr = 0x01;
  870. X    ptr++;
  871. X    if (Lh & mask)
  872. X    *ptr = 0x01;
  873. X    ptr++;
  874. X    mask = 0x000002L;
  875. X    if (Rl & mask)
  876. X    *ptr = 0x01;
  877. X    ptr++;
  878. X    if (Ll & mask)
  879. X    *ptr = 0x01;
  880. X    ptr++;
  881. X    mask = 0x002000L;
  882. X    if (Rl & mask)
  883. X    *ptr = 0x01;
  884. X    ptr++;
  885. X    if (Ll & mask)
  886. X    *ptr = 0x01;
  887. X    ptr++;
  888. X    mask = 0x000002L;
  889. X    if (Rh & mask)
  890. X    *ptr = 0x01;
  891. X    ptr++;
  892. X    if (Lh & mask)
  893. X    *ptr = 0x01;
  894. X    ptr++;
  895. X    mask = 0x002000L;
  896. X    if (Rh & mask)
  897. X    *ptr = 0x01;
  898. X    ptr++;
  899. X    if (Lh & mask)
  900. X    *ptr = 0x01;
  901. X    ptr++;
  902. X}
  903. X
  904. Xchar *
  905. Xfcrypt (pw, salt)
  906. X    char *pw;
  907. X    char *salt;
  908. X{
  909. X    /* Table lookups for salts reduce fcrypt() overhead dramatically */
  910. X    static sbpb24 salt0[] =
  911. X    {
  912. X    18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  913. X    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  914. X    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  915. X    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 5, 6, 7, 8, 9, 10, 11, 12,
  916. X    13, 14, 15, 16, 17,
  917. X
  918. X    18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  919. X    32, 33, 34, 35, 36, 37, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
  920. X    42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
  921. X    58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
  922. X    12, 13, 14, 15, 16, 17,
  923. X
  924. X    18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  925. X    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  926. X    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  927. X    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
  928. X
  929. X    18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  930. X    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  931. X    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  932. X    0, 1, 2, 3, 4
  933. X    };
  934. X    static sbpb24 salt1[] =
  935. X    {
  936. X    1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
  937. X    1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
  938. X    2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944,
  939. X    3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584,
  940. X    3648, 3712, 3776, 3840, 3904, 3968, 4032, 0, 64, 128, 192, 256,
  941. X    320, 384, 448, 512, 576, 640, 704, 320, 384, 448, 512, 576, 640,
  942. X    704, 768, 832, 896, 960, 1024, 1088,
  943. X
  944. X    1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
  945. X    1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
  946. X    2368, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560,
  947. X    2624, 2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136, 3200,
  948. X    3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840,
  949. X    3904, 3968, 4032, 0, 64, 128, 192, 256, 320, 384, 448, 512, 576,
  950. X    640, 704, 768, 832, 896, 960, 1024, 1088,
  951. X
  952. X    1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
  953. X    1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
  954. X    2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944,
  955. X    3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584,
  956. X    3648, 3712, 3776, 3840, 3904, 3968, 4032, 0, 64, 128, 192, 256,
  957. X    320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024,
  958. X    1088,
  959. X
  960. X    1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
  961. X    1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
  962. X    2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944,
  963. X    3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584,
  964. X    3648, 3712, 3776, 3840, 3904, 3968, 4032, 0, 64, 128, 192, 256
  965. X    };
  966. X
  967. X    /* final perutation desalting */
  968. X    static obpb1 final[] =
  969. X    {
  970. X    46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66,
  971. X    67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
  972. X    83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103,
  973. X    104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
  974. X    117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
  975. X    130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
  976. X    143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
  977. X    156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
  978. X    169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
  979. X    182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
  980. X    195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
  981. X    208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
  982. X    221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
  983. X    234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
  984. X    247, 248, 249, 250, 251, 252, 253, 254, 255,
  985. X        /* Truncate overflow bits at 256 */
  986. X    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  987. X    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  988. X    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  989. X    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58
  990. X    };
  991. X
  992. X    reg int i, j, k;
  993. X    reg long int *lip;
  994. X    sbpb24 saltvalue;
  995. X
  996. X#ifdef BUILTIN_CLEAR
  997. X    lip = (long int *) crypt_block;
  998. X    for (i = (sizeof (crypt_block) / sizeof (long int)); i--; /* - */ )
  999. X    {
  1000. X    *(lip++) = 0L;
  1001. X    }
  1002. X#else                /* BUILTIN_CLEAR */
  1003. X    bzero (crypt_block, 66);
  1004. X#endif                /* BUILTIN_CLEAR */
  1005. X
  1006. X    for (i = 0; (k = *pw) && i < 64; pw++)
  1007. X    {
  1008. X    crypt_block[i++] = (k >> 6) & 01;
  1009. X    crypt_block[i++] = (k >> 5) & 01;
  1010. X    crypt_block[i++] = (k >> 4) & 01;
  1011. X    crypt_block[i++] = (k >> 3) & 01;
  1012. X    crypt_block[i++] = (k >> 2) & 01;
  1013. X    crypt_block[i++] = (k >> 1) & 01;
  1014. X    crypt_block[i++] = (k >> 0) & 01;
  1015. X    i++;            /* have to skip one here (parity bit) */
  1016. X    }
  1017. X
  1018. X    fsetkey ( /* crypt_block */ );
  1019. X
  1020. X#ifdef BUILTIN_CLEAR
  1021. X    lip = (long int *) crypt_block;
  1022. X    for (i = (sizeof (crypt_block) / sizeof (long int)); i--; /* - */ )
  1023. X    {
  1024. X    *(lip++) = 0L;
  1025. X    }
  1026. X#else                /* BUILTIN_CLEAR */
  1027. X    bzero (crypt_block, 66);
  1028. X#endif                /* BUILTIN_CLEAR */
  1029. X
  1030. X    iobuf[0] = salt[0];
  1031. X    iobuf[1] = salt[1];
  1032. X
  1033. X    saltvalue = salt0[iobuf[0]] | salt1[iobuf[1]];
  1034. X    saltvalue = TF_TO_SIXBIT (saltvalue);
  1035. X
  1036. X    XForm (saltvalue);
  1037. X    UnXForm ();
  1038. X
  1039. X    for (i = 0; i < 11; i++)
  1040. X    {
  1041. X    k = 0;
  1042. X
  1043. X    for (j = 0; j < 6; j++)
  1044. X    {
  1045. X        k = (k << 1) | crypt_block[SIX_TIMES (i) + j];
  1046. X    }
  1047. X    iobuf[i + 2] = final[k];
  1048. X    }
  1049. X
  1050. X    iobuf[i + 2] = 0;
  1051. X
  1052. X    if (iobuf[1] == 0)
  1053. X    {
  1054. X    iobuf[1] = iobuf[0];
  1055. X    }
  1056. X    return (iobuf);
  1057. X}
  1058. X/********* INITIALISATION ROUTINES *********/
  1059. X
  1060. Xfbpb4
  1061. XlookupS (tableno, t6bits)
  1062. X    unsl tableno;
  1063. X    sbpb6R t6bits;
  1064. X{
  1065. X    static fbpb4R S[8][64] =
  1066. X    {
  1067. X    14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
  1068. X    0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
  1069. X    4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
  1070. X    15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
  1071. X
  1072. X    15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
  1073. X    3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
  1074. X    0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
  1075. X    13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
  1076. X
  1077. X    10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
  1078. X    13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
  1079. X    13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
  1080. X    1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
  1081. X
  1082. X    7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
  1083. X    13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
  1084. X    10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
  1085. X    3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
  1086. X
  1087. X    2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
  1088. X    14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
  1089. X    4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
  1090. X    11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
  1091. X
  1092. X    12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
  1093. X    10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
  1094. X    9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
  1095. X    4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
  1096. X
  1097. X    4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
  1098. X    13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
  1099. X    1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
  1100. X    6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
  1101. X
  1102. X    13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
  1103. X    1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
  1104. X    7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
  1105. X    2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
  1106. X    };
  1107. X    sbpb6 fixed6bits;
  1108. X    fbpb4R r;
  1109. X    fbpb4 fixedr;
  1110. X
  1111. X    fixed6bits = (((t6bits >> 0) & 01) << 5) +
  1112. X    (((t6bits >> 1) & 01) << 3) +
  1113. X    (((t6bits >> 2) & 01) << 2) +
  1114. X    (((t6bits >> 3) & 01) << 1) +
  1115. X    (((t6bits >> 4) & 01) << 0) +
  1116. X    (((t6bits >> 5) & 01) << 4);
  1117. X
  1118. X    r = S[tableno][fixed6bits];
  1119. X
  1120. X    fixedr = (((r >> 3) & 01) << 0) +
  1121. X    (((r >> 2) & 01) << 1) +
  1122. X    (((r >> 1) & 01) << 2) +
  1123. X    (((r >> 0) & 01) << 3);
  1124. X
  1125. X    return (fixedr);
  1126. X}
  1127. X
  1128. Xvoid
  1129. Xinit (tableno, lowptr, highptr)
  1130. X    unsl tableno;
  1131. X    sbpb24 *lowptr, *highptr;
  1132. X{
  1133. X
  1134. X    static unsb P[] =
  1135. X    {
  1136. X    15, 6, 19, 20,
  1137. X    28, 11, 27, 16,
  1138. X    0, 14, 22, 25,
  1139. X    4, 17, 30, 9,
  1140. X    1, 7, 23, 13,
  1141. X    31, 26, 2, 8,
  1142. X    18, 12, 29, 5,
  1143. X    21, 10, 3, 24,
  1144. X    };
  1145. X
  1146. X    static unsb E[] =
  1147. X    {
  1148. X    31, 0, 1, 2, 3, 4,
  1149. X    3, 4, 5, 6, 7, 8,
  1150. X    7, 8, 9, 10, 11, 12,
  1151. X    11, 12, 13, 14, 15, 16,
  1152. X    15, 16, 17, 18, 19, 20,
  1153. X    19, 20, 21, 22, 23, 24,
  1154. X    23, 24, 25, 26, 27, 28,
  1155. X    27, 28, 29, 30, 31, 0,
  1156. X    };
  1157. X
  1158. X    static obpb1 tmp32[32];
  1159. X    static obpb1 tmpP32[32];
  1160. X    static obpb1 tmpE[48];
  1161. X
  1162. X    int j, k, i;
  1163. X    int tablenoX4;
  1164. X    reg sbpb24 spare24;
  1165. X
  1166. X    tablenoX4 = tableno * 4;
  1167. X
  1168. X    for (j = 0; j < 64; j++)
  1169. X    {
  1170. X    k = lookupS (tableno, j);
  1171. X
  1172. X    for (i = 0; i < 32; i++)
  1173. X    {
  1174. X        tmp32[i] = 0;
  1175. X    }
  1176. X    for (i = 0; i < 4; i++)
  1177. X    {
  1178. X        tmp32[tablenoX4 + i] = (k >> i) & 01;
  1179. X    }
  1180. X    for (i = 0; i < 32; i++)
  1181. X    {
  1182. X        tmpP32[i] = tmp32[P[i]];
  1183. X    }
  1184. X    for (i = 0; i < 48; i++)
  1185. X    {
  1186. X        tmpE[i] = tmpP32[E[i]];
  1187. X    }
  1188. X
  1189. X    lowptr[j] = 0;
  1190. X    highptr[j] = 0;
  1191. X
  1192. X    for (i = 0; i < 24; i++)
  1193. X    {
  1194. X        lowptr[j] |= (unsigned long) tmpE[i] << i;
  1195. X    }
  1196. X    for (k = 0, i = 24; i < 48; i++, k++)
  1197. X    {
  1198. X        highptr[j] |= (unsigned long) tmpE[i] << k;
  1199. X    }
  1200. X
  1201. X    spare24 = lowptr[j];    /* to allow for macro expansion */
  1202. X    lowptr[j] = TF_TO_SIXBIT (spare24);
  1203. X    spare24 = highptr[j];    /* to allow for macro expansion */
  1204. X    highptr[j] = TF_TO_SIXBIT (spare24);
  1205. X    }
  1206. X}
  1207. Xinit_des ()
  1208. X{
  1209. X    init (0L, S0L, S0H);
  1210. X    init (1L, S1L, S1H);
  1211. X    init (2L, S2L, S2H);
  1212. X    init (3L, S3L, S3H);
  1213. X    init (4L, S4L, S4H);
  1214. X    init (5L, S5L, S5H);
  1215. X    init (6L, S6L, S6H);
  1216. X    init (7L, S7L, S7H);
  1217. X}
  1218. END_OF_FILE
  1219. if test 22754 -ne `wc -c <'Sources/crack-fcrypt.c'`; then
  1220.     echo shar: \"'Sources/crack-fcrypt.c'\" unpacked with wrong size!
  1221. fi
  1222. # end of 'Sources/crack-fcrypt.c'
  1223. fi
  1224. echo shar: End of archive 3 \(of 5\).
  1225. cp /dev/null ark3isdone
  1226. MISSING=""
  1227. for I in 1 2 3 4 5 ; do
  1228.     if test ! -f ark${I}isdone ; then
  1229.     MISSING="${MISSING} ${I}"
  1230.     fi
  1231. done
  1232. if test "${MISSING}" = "" ; then
  1233.     echo You have unpacked all 5 archives.
  1234.     rm -f ark[1-9]isdone
  1235. else
  1236.     echo You still need to unpack the following archives:
  1237.     echo "        " ${MISSING}
  1238. fi
  1239. ##  End of shell archive.
  1240. exit 0
  1241. exit 0 # Just in case...
  1242. -- 
  1243. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1244. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1245. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1246. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1247.