home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume22 / crack / part03 < prev    next >
Text File  |  1991-08-23  |  48KB  |  1,464 lines

  1. Newsgroups: comp.sources.misc
  2. From: Alec David Muffett <aem@aber.ac.uk>
  3. Subject:  v22i051:  crack - The Password Cracker, version 3.2a, Part03/04
  4. Message-ID: <1991Aug23.150438.1061@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: bfc74b025bd6d09f1fd67571cb6bc8cb
  6. Date: Fri, 23 Aug 1991 15:04:38 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Alec David Muffett <aem@aber.ac.uk>
  10. Posting-number: Volume 22, Issue 51
  11. Archive-name: crack/part03
  12. Environment: UNIX
  13.  
  14. #! /bin/sh
  15. # it by saving it into a file and typing "sh file".  To overwrite existing
  16. # files, type "sh file -c".  You can also feed this as standard input via
  17. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  18. # will see the following message at the end:
  19. #        "End of archive 3 (of 4)."
  20. # Contents:  Docs/README.ms Sources/crack-fcrypt.c
  21. # Wrapped by aem@aberda on Fri Aug 23 13:20:42 1991
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'Docs/README.ms' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'Docs/README.ms'\"
  25. else
  26. echo shar: Extracting \"'Docs/README.ms'\" \(20032 characters\)
  27. sed "s/^X//" >'Docs/README.ms' <<'END_OF_FILE'
  28. X.de C
  29. X.ie n .B "\\$1" \\$2
  30. X.el .CW "\\$1" \\$2
  31. X..
  32. X.TL
  33. X"Crack Version 3.2"
  34. X.br
  35. XA Sensible Password Checker for
  36. X.UX
  37. X.AU
  38. XAlec D.E. Muffett
  39. X.AI
  40. XComputer Unit, University College of Wales
  41. XAberystwyth, Wales, SY23 3DB
  42. X.I aem@aber.ac.uk
  43. X+44 970 622492
  44. X.AB
  45. X.B Crack \**
  46. X.FS
  47. X.C Crack
  48. Xis available for anonymous FTP from
  49. X.I "wuarchive.wustl.edu"
  50. X(128.252.135.4) in
  51. X.I ~/packages
  52. X.FE
  53. Xis a freely available program designed to find standard
  54. X.UX
  55. Xeight-character DES encrypted passwords by standard guessing techniques
  56. Xoutlined below.  It is written to be flexible, configurable and fast,
  57. Xand to be able to make use of several networked hosts via the Berkeley
  58. X.C rsh
  59. Xprogram (or similar), where possible.
  60. X.AE
  61. X.NH 1
  62. XIntent of this program
  63. X.LP
  64. XMy intentions, whilst writing this program, were
  65. X.IP 1)
  66. XTo provide the average system manager with a simple, flexible and fast
  67. Xtool to find passwords which would be easily compromised by a dictionary
  68. Xsearch.
  69. X.IP 2)
  70. XTo weaken the complacency which has developed amongst many (in)?experienced
  71. X.UX
  72. Xsystems managers about password security. Just because the
  73. X.C crypt()
  74. Xfunction cannot be reversed does not mean that your passwords are
  75. Xsecure.  If this program helps to raise the overall quotient of paranoia
  76. Xjust one little bit, then it will have served its purpose and is all to
  77. Xthe good.
  78. X.LP
  79. XI am quite certain that some childish morons out there will abuse the
  80. Xwork that I have put into creating this program.  It's up to them how
  81. Xthey use it, but if it's used for some illegal purpose it's not my
  82. Xintention, nor my fault. I hope they get caught.
  83. X.LP
  84. XCrack was not designed to do anything
  85. X.I nasty ,
  86. Xother than to attack passwords in sensible order.  This is why I feel I
  87. Xcan post it to the net without fear of recrimination.  
  88. XThis version of Crack is supplied with a (hopefully) portable version of
  89. X.C fcrypt() ,
  90. Xfor speed reasons.  Fcrypt() is not yet widely available, but several
  91. Xversions have now been posted to USENET, and with the growing ability to
  92. Xaccess anonymous FTP databases like
  93. X.B Archie ,
  94. XI believe that people who really want access to such programs as
  95. Xfcrypt() will be able to get them easily.  People who need them but
  96. Xdon't have the time to look, on the other hand, will not get them.  This
  97. Xis not a good thing if you are a systems manager, because it gives the
  98. Xcrackers an advantage.  My philosophy is:
  99. X.I "give it to everyone, then at least the people who need it can get it" .
  100. X.NH 1
  101. XFcrypt() Statistics
  102. X.LP
  103. XThe version of fcrypt() that comes with Crack is some 3.4 times faster
  104. Xthan the version that was originally supplied to me, and should
  105. Xoutperform most others which are publicly available.  I haven't tried
  106. Xmany speed-demon style tricks, but rather I have gone for portability,
  107. Xelegance and simplicity, where applicable 
  108. X.C 8-).  
  109. XOn a DECStation 5000/200, fcrypt() iterates ~550 times per second, and
  110. Xoverall, I measure this to be 13 times faster than standard crypt(). 
  111. XThere are faster versions available, but at least I feel free to
  112. Xredistrubute this version without stepping on anyones toes. 
  113. X.LP
  114. XA final note about my motives: If you think that I am a moron for
  115. Xwriting and then distributing this program, and you think that the
  116. Xprogram is in itself dangerous, I suggest that you carefully consider
  117. Xthe fact that any moron could have written this program.  Flames to
  118. X.C /dev/null ,
  119. Xplease.
  120. X.NH 1
  121. XImplementation
  122. X.LP
  123. XI have tried to make Crack as portable as possible without compromising
  124. Xspeed.  Needless to say, it is imperfect in the this respect, but I have
  125. Xtried.  If you have problems getting Crack up, please let me know what
  126. Xthese problems were, and what system you were trying to put Crack up on. 
  127. XI believe that Crack will work on
  128. X.B Xenix
  129. Xand various versions of
  130. X.B "System V" ,
  131. Xbut it may require a little effort if your
  132. X.UX
  133. Xis not fairly modern.
  134. X.LP
  135. XThere have been some nasty stories sent back to me about problems
  136. Xencountered due to the Crack script being written in c-shell.  Because
  137. Xof this, I enclose a program
  138. X.C Crack.sh
  139. Xwhich is a functionally equivalent script in Bourne shell, using
  140. X.C nohup
  141. Xto kick the cracker off into the background.  If your version of c-shell
  142. Xis non standard (ie: not BSDish) or you are worried, you may use
  143. X.C Crack.sh
  144. Xin
  145. X.C Crack 's
  146. Xplace.  Note, though, that if you want to use the network options, you
  147. Xwill also have to edit
  148. X.C Scripts/RCrack
  149. Xto change the program-name that is called on remote machines to
  150. X.C Crack.sh .
  151. XFor more on this, see below.
  152. X.LP
  153. XTo use the
  154. X.C "Crack -network"
  155. Xoption, you must have
  156. X.C rsh ,
  157. Xor a similar program. 
  158. X.C rsh 
  159. Xis a BSD-ism which has become fairly common on non-BSD systems.  If you
  160. Xdon't have it or something similar, let me know what you do have which
  161. Xmight, with a little ingenuity, do the job, and I shall see what I can
  162. Xdo.  Again, have a look in
  163. X.C Scripts/RCrack
  164. Xif you want to play around.
  165. X.QP
  166. X.B Note:
  167. X.B Xenix
  168. Xusers and some others have a
  169. X.C rcmd
  170. Xprogram instead of
  171. X.C rsh .
  172. XI'm not sure of the correct syntax for this program, but it should not
  173. Xbe hard to get it to work.  There is a note about it in
  174. X.C Scripts/RCrack
  175. X.QP
  176. XOn such System V based systems, users may also be missing the BSD
  177. Xfunction
  178. X.C gethostname() .
  179. XIf this is so, but you 
  180. X.B do 
  181. Xhave the
  182. X.C uname()
  183. Xsystem call, define the macro
  184. X.C CRACK_UNAME
  185. Xin
  186. X.C Sources/conf.h
  187. Xinstead. This ought to fix the problem, but it
  188. X.I may
  189. Xneed a little user intervention first (it depends where your header file for 
  190. X.C uname()
  191. Xis).
  192. X.I "Caveat Emptor!"
  193. X.NH 1
  194. XMethod of Password Cracking
  195. X.LP
  196. XCrack does not take the serial approach to password guessing that other
  197. Xprograms like the
  198. X.B COPS
  199. Xpassword cracker does.  Rather, Crack makes two passes over the users'
  200. Xpassword entries.
  201. X.LP
  202. XThe first pass bases its guesses on the contents of the
  203. X.I gecos
  204. Xfield (containing the users' real name), and the username itself.  The
  205. Xfirst pass is fast and usually very fruitful, and completes quite
  206. Xquickly.  You would be surprised at the number of spods out there who
  207. Xstill think that their middle name, backwards and capitalised, is a good
  208. Xpassword.
  209. X.LP
  210. XThe second pass is made by encrypting several pre-processed dictionaries
  211. Xon the fly, and comparing the results with users passwords.  Crack
  212. Xoptimises the number of calls to the encryption function by sorting the
  213. Xuser passwords by their
  214. X.I "encryption salt"
  215. Xbefore loading, so that the dictionaries only have to be encrypted once
  216. Xfor each different salt.  This generally saves about 30% of the calls
  217. Xyou would have to make to
  218. X.C crypt() .
  219. X.LP
  220. XThe preprocessed dictionaries are created my merging the source
  221. Xdictionaries found in the directory
  222. X.C DictSrc
  223. Xand then truncating, sorting and uniq'ing the output from the
  224. Xpreprocessor.  The default dictionaries named are
  225. X.C /usr/dict/words
  226. Xwhich provides the bulk of the input data, and
  227. X.C DictSrc/bad_pws.dat
  228. Xwhich is meant to provide all of those non-dictionary passwords, such as
  229. X.I 12345678
  230. Xor
  231. X.I qwerty .\**
  232. X.FS
  233. XExtra dictionaries (those used in Dan Klein's paper, below) can be
  234. Xobtained via anonymous FTP from
  235. X.I uunet.uu.net
  236. X(192.48.96.2) as
  237. X.I ~/pub/dictionaries.tar.Z
  238. X.FE
  239. X.LP
  240. XIf you wish to add a dictionary of your own, just copy it into the 
  241. X.C DictSrc
  242. Xdirectory and then delete the contents of the 
  243. X.C Dicts
  244. Xdirectory.  Your new dictionary will be merged in on the next run.  Do
  245. Xnot worry about replication of data, as the preprocessor driver script
  246. Xsorts and uniq's the data before putting it into the
  247. X.C Dicts
  248. Xdirectory.
  249. X.LP
  250. XThe formats of the output dictionaries are:
  251. X.IP a)
  252. XUnique words that have been forced lowercase, forwards.  These are the
  253. Xmost common passwords you will find, thus they are tried first.
  254. X.IP b)
  255. XDictionary words which have been artificially pluralised, because not
  256. Xmany dictionaries contain plurals.
  257. X.IP c)
  258. XDictionary words which were supplied in mixed-case (eg:
  259. X.I Capitalised ).
  260. X.IP d)
  261. XDictionary words forced lowercase and backwards.
  262. X.IP e)
  263. XDictionary words, forced lowercase, with a leading or trailing 0 or 1
  264. X(this may be extended by hacking Sources/crack-pp.c). 
  265. X.IP f)
  266. XDictionary words, forced uppercase, forwards.
  267. X.IP g)
  268. XDictionary words, forced uppercase, backwards.
  269. X.IP h)
  270. XDictionary words which were supplied in mixed-case, backwards (eg:
  271. X.I desilatipaC ).
  272. X.sp 1v
  273. X.LP
  274. XThis choice of attack is entirely empirical, my own, and made up on the
  275. Xspot.  It has also been horrendously successful, and because Crack uses
  276. Xeach of these dictionaries in turn, it tends to get passwords faster
  277. Xthan a program like the
  278. X.B COPS
  279. Xpassword cracker which tries words every-which-way for each user.\**
  280. X.FS
  281. XFor more information, see "Foiling the Cracker: A Survey of, and
  282. XImprovements to, Password Security" by Daniel Klein, available from
  283. Xmajor FTP sites. 
  284. X.FE
  285. X.QP
  286. XOptimisation Note: Crack has an
  287. X.B compile-time
  288. Xoption, called
  289. X.C CRACK_SHORT_PASSWDS ,
  290. Xwhich, if
  291. X.B not
  292. Xdefined, makes the dictionary preprocessor
  293. X.I "throw away"
  294. Xwords which are less than 5 characters long.  The reasoning for this is
  295. Xthat many sites, with a semi-sensible
  296. X.C passwd
  297. Xprogram, will not have passwords shorter than 5 characters long.  
  298. X.QP 
  299. XIt is up to you whether you bother testing these short passwords, but I
  300. Xwould recommend that you do so at least once, to be safe.  (Setting the
  301. Xoption also leads to having smaller pre-processed dictionaries.  The
  302. Xoption, however, is defined by default)
  303. X.NH 1
  304. XInstallation
  305. X.LP 
  306. XCrack is one of those most unusual of beasties, a self-installing
  307. Xprogram.  Once the necessary configuration options have been set, the
  308. Xexecutables are created via 'make' by running the main shellscript.  
  309. X.LP
  310. XSome people have complained about this apparent weirdness, but it has
  311. Xgrown up with Crack ever since the earliest network version, when I
  312. Xcould not be bothered to log into several different machines with
  313. Xseveral different architectures, just in order to build the binaries. 
  314. X.LP
  315. XCrack needs to know where it has been installed.  Please edit the
  316. X.C CRACK_HOME
  317. Xvariable in the Crack shellscript to the correct value.  This variable
  318. Xshould be set to an absolute path name (relative to
  319. X.I ~user
  320. Xis OK) through which the directory containing Crack may be accessed on
  321. X.B all
  322. Xthe machines that Crack will be run on.
  323. X.LP
  324. XThe other bit of installation you will have to do is decide whether
  325. Xyou will want to use the
  326. X.C \&-network
  327. Xoption. If you do, edit the file
  328. X.C Sources/conf.h
  329. Xand define the
  330. X.C CRACK_NETWORK
  331. Xsymbol.  This forces Crack to create all of its output files with an
  332. Xembedded hostname (obtained by the
  333. X.C gethostname()
  334. Xroutine) so that you can keep track of output from all over the network.
  335. XIf you have no
  336. X.C gethostname()
  337. Xbut have a
  338. X.C uname()
  339. Xsystem call, you can use that instead, by defining
  340. X.C CRACK_UNAME
  341. Xin
  342. X.C Sources/conf.h .
  343. X.LP
  344. XYou will then have to generate a 
  345. X.C Scripts/network.conf
  346. Xfile. This contains a list of hostnames to 
  347. X.C rsh
  348. Xto, what their binary type is (useful when running a network Crack on
  349. Xseveral different architectures), a guesstimate of their relative power
  350. X(take your slowest machine as unary, and measure all others relative to
  351. Xit), and a list of per-host default flags.  There is an example of such
  352. Xa file provided in the Scripts directory - take a look at it. 
  353. X.LP
  354. XI also recommend that you play around with the
  355. X.C #define s
  356. Xin the file
  357. X.C Sources/conf.h .
  358. XEach switch has a small note explaining its meaning.  Where I've been in
  359. Xdoubt about the portability of certain library functions, usually I've
  360. Xre-written it, so it shouldn't be much of a problem.  Let me know of
  361. Xyour problems.  
  362. X.C 8-).
  363. X.NH 1
  364. XCrack Usage
  365. X.LP
  366. X.DS B
  367. X.fi
  368. X.C Crack
  369. X[\c
  370. X.I options ]
  371. X[\c
  372. X.I bindir ]
  373. X.C /etc/passwd
  374. X[...other passwd files]
  375. X.sp 1v
  376. X.C "Crack -network"
  377. X[\c
  378. X.I options ]
  379. X.C /etc/passwd
  380. X[...other passwd files]
  381. X.DE
  382. X.LP
  383. XWhere
  384. X.B bindir
  385. Xis the optional name of the directory where you want the binaries
  386. Xinstalled.  This is useful where you want to be able to run versions of
  387. XCrack on several different architectures. If
  388. X.B bindir
  389. Xdoes not exist, a warning will be issued, and the directory, created.
  390. X.QP
  391. XNote:
  392. X.B bindir
  393. Xdefaults to the name
  394. X.C generic
  395. Xif not supplied.
  396. X.QP 
  397. X.B "Yellow Pages (NIS) Users:"
  398. XI have had some queries about how to get Crack running from a YP
  399. Xpassword file.  There are several methods, but by far the simplest is to
  400. Xgenerate a passwd format file by running:-
  401. X.DS B
  402. X.C "ypcat passwd > passwd.yp"
  403. X.DE
  404. Xand then running Crack on this file.
  405. X.NH 1
  406. XOptions
  407. X.IP "\fB-network\fP"
  408. XThrows Crack into network mode, in which it reads the
  409. X.C Scripts/network.conf
  410. Xfile, splits its input into chunks which are sized according to the
  411. Xpower of the target machine, and calls
  412. X.C rsh
  413. Xto run Crack on that machine.  Options for Crack running on the target
  414. Xmachine may be supplied on the command line (eg: verbose or recover
  415. Xmode), or in the network.conf file if they pertain to specific hosts
  416. X(eg:
  417. X.C nice() 
  418. Xvalues). 
  419. X.IP "\fB-v\fP"
  420. XSets verbose mode, whereby Crack will print every guess it is trying on
  421. Xa per-user basis.  This is a very quick way of flooding your filestore. 
  422. XIf you undefine the
  423. X.C CRACK_VERBOSE
  424. Xsymbol in
  425. X.C Sources/conf.h ,
  426. Xverbose mode will be permanently disabled.
  427. X.IP "\fB-nvalue\fP"
  428. XSets the process to be
  429. X.C nice() ed
  430. Xto
  431. X.I value ,
  432. Xso that the switch
  433. X.C \&-n19
  434. Xsets the Crack process to run at the lowest priority.
  435. X.IP "\fB-rpointfile\fP"
  436. XThis is only for use when running in
  437. X.I recover
  438. Xmode.  When a running Crack starts pass 2, it periodically saves its
  439. Xstate in a file named
  440. X.C "point.<pid>"
  441. Xor
  442. X.C "point.<hostname>.<pid>"
  443. Xdepending on your naming convention (see "Installation", above).  This
  444. Xfile can be used to recover where you were should a host crash.  Simply
  445. Xinvoke Crack in
  446. X.B exactly
  447. Xthe same manner as the last time, with the addition of the
  448. X.C -rpoint.file.name
  449. Xswitch.  Crack will startup and read the file, and jump to slightly
  450. Xbefore where it left off.  If you are cracking a very large password
  451. Xfile, this can save oodles of time after a crash.
  452. X.QP
  453. XIf you are running a
  454. X.I network
  455. XCrack, then the jobs will again be spawned onto all the machines of the
  456. Xoriginal Crack.  The program will then check that the host it is running
  457. Xon is the same as is mentioned in the pointfile.  If it is not, it will
  458. Xsilently die.  Thus, assuming that you supply the same input data and do
  459. Xnot change your
  460. X.C network.conf
  461. Xfile, Crack should pick up
  462. X.B exactly
  463. Xwhere it left off.  This is a bit inelegant, but it's better than
  464. Xnothing at the moment.
  465. X.NH
  466. XMultiprocessing and parallelism
  467. X.LP
  468. XThe method of error recovery outlined above causes headaches for users
  469. Xwho want to do multiprocessing on parallel architectures.  Crack is in
  470. Xno way parallel, and because of the way it's structured, readind stdin
  471. Xfrom shellscript frontends, it is a pain to divide the work amongst
  472. Xseveral processes via
  473. X.C fork() ing.
  474. X.LP
  475. XThe hack solution to get several copies of Crack running on one machine
  476. Xwith
  477. X.I n
  478. Xprocessors at the moment is to run with the
  479. X.C CRACK_NETWORK
  480. Xoption enabled, and insert
  481. X.I n
  482. Xcopies of the entry for your parallel machine into the
  483. X.C Scripts/network.conf
  484. Xfile. If you use the
  485. X.C \&-r
  486. Xoption in these circumstances however, you will get
  487. X.I n
  488. Xcopies of the recovered process running, only one of them will have the
  489. Xcorrect input data.  I'm working on this.  My current solution is to
  490. Xsave the current username in the checkpoint file, and test it on
  491. Xstartup, but doing this
  492. X.I may
  493. Xbreak your recovery if you supply different input data (so that the data
  494. Xis sorted even slightly differently).  Hohum.  If you want to use this
  495. X.I "verify username"
  496. Xfacility, use
  497. X.C \&-R
  498. Xin place of
  499. X.C \&-r .
  500. X.LP
  501. XAs for not using the
  502. X.C network.conf
  503. Xfile to provide multiprocessing, I'm working on it.
  504. X.NH 1
  505. XNotes on fast crypt() implementations
  506. X.LP
  507. XThe stdlib version of the
  508. X.C crypt()
  509. Xsubroutine is incredibly slow.  It is a
  510. X.I massive
  511. Xbottleneck to the execution of Crack and on typical platforms that you
  512. Xget at universities, it is rare to find a machine which will achieve
  513. Xmore than 50 standard
  514. X.C crypt() s
  515. Xper second.  On low-end diskless workstations, you may expect 2 or 3 per
  516. Xsecond.  It was this slowness of the
  517. X.C crypt()
  518. Xalgorithm which originally supplied much of the security
  519. X.UX
  520. Xneeded.\**
  521. X.FS
  522. XSee: "Password Security, A Case History" by Bob Morris & Ken Thomson, in
  523. Xthe
  524. X.UX
  525. XProgrammer Docs.
  526. X.FE
  527. X.LP
  528. XHowever, there are now
  529. X.C many
  530. Ximplementations of faster versions of
  531. X.C crypt()
  532. Xto be found on the network.  The one supplied with Crack v3.2 and
  533. Xupwards is called
  534. X.C fcrypt() .
  535. X.LP
  536. X.C fcrypt()
  537. Xwas originally written in May 1986 by Robert Baldwin at MIT, and is a
  538. Xgood version of the
  539. X.C crypt()
  540. Xsubroutine.  I received a copy from Icarus Sparry at Bath University,
  541. Xwho had made a couple of portability enhancements to the code.
  542. X.LP
  543. XI rewrote most of the tables and the KeySchedule generating algorithm in
  544. Xthe original
  545. X.I fdes-init.c
  546. Xto knock 40% off the execution overhead of
  547. X.C fcrypt()
  548. Xin the form that it was shipped to me.  I inlined a bunch of stuff, put
  549. Xit into a single file, got some advice from Matt Bishop and Bob Baldwin
  550. X[both of whom I am greatly indebted to] about what to do to the
  551. X.C xform()
  552. Xroutine and to the fcrypt function itself, and tidied up some algorithms.
  553. XI've also added more lookup tables and reduced several formula for
  554. Xfaster use.
  555. X.C fcrypt()
  556. Xis now barely recognisable as being based on its former incarnation.
  557. X.LP
  558. XOn a DecStation 5000/200, it is also ~13 times faster than the standard
  559. Xcrypt (your mileage may vary with other architectures and compilers).
  560. XThis speed puts
  561. X.C fcrypt()
  562. Xinto the "moderately fast" league of crypt implementations.  By using
  563. X.C fcrypt()
  564. Xwith Crack, I extracted 135 passwords from my standard 1087 user
  565. Xpassword file in a little over 1 hour using 3 networked machines.  This
  566. Xis from a moderately good password file.
  567. X.LP
  568. XWhy am I saying this sort of thing ? Am I scaremongering ? In a word, yes.
  569. X.LP
  570. XIf a fast version of
  571. X.C crypt()
  572. Xis wired into a program like Crack it can break a poorly passworded site
  573. Xopen in minutes.  There are such programs available, eg: the "Killer
  574. XCracker" written by the anonymous "Doctor Dissector", with anonymous
  575. Xmotives.  It comes with a modified version of Baldwin's fcrypt, as a
  576. XMS-DOS executable with a GNU copyleft licence.
  577. X.LP
  578. XThe point that needs to be hammered home is that unless something is
  579. Xdone, and done soon, about the general quality of passwords on
  580. X.UX
  581. Xsystems, then in the near future our doors will be wide open to people
  582. Xwho have programs like Crack and questionable motives.
  583. X.NH 1
  584. XSolutions and Conclusions
  585. X.LP
  586. XWhat can be done about this form of attack ?
  587. X.LP
  588. XYou must get a drop-in replacement for the
  589. X.C passwd
  590. Xand
  591. X.C yppasswd
  592. Xcommands; one which will stop people from choosing bad passwords in the
  593. Xfirst place.  There are several programs to do this; Matt Bishop's
  594. X.C "passwd+"
  595. Xand Clyde Hoover's
  596. X.C "npasswd"
  597. Xprogram are good examples which are freely available.  Consult an
  598. X.B Archie
  599. Xdatabase for more details on where you can get them from.
  600. X.LP
  601. XA little common-sense is all that is required to vet passwords: I
  602. Xenclose a module in the Sources directory
  603. X.I goodpass.c
  604. Xwhich I use in a modified version of the
  605. X.C yppasswd
  606. Xin order to provide some security.  It is quite heavily customised for
  607. Xuse in the UK, but it should be easily portable.  The routine is invoked:
  608. X.sp 1v
  609. X.DS B
  610. X.C "char *retval = GoodPass(char *input);"
  611. X.DE
  612. X.LP
  613. Xwhere
  614. X.C input
  615. Xis the password under test, and
  616. X.C retval
  617. Xwill be set either to NULL (if the password is OK) or to a diagnostic
  618. Xstring which says what is wrong with the password.  It is far less
  619. Xcomplex than a system such as
  620. X.I passwd+ ,
  621. Xbut still effective enough to make a password file withstand
  622. X.C Crack .
  623. XIt would be nice if an organisation (such as
  624. X.B CERT ?)
  625. Xcould be persuaded to supply skeletons of
  626. X.I sensible
  627. Xpasswd commands for the public good, as well as an archive of security
  628. Xrelated utilities\**
  629. Xon top of the excellent
  630. X.C COPS .
  631. X.FS
  632. X.C COPS
  633. Xis available for anonymous FTP from
  634. X.I "cert.sei.cmu.edu"
  635. X(128.237.253.5) in
  636. X.I ~/cops
  637. X.FE
  638. XHowever, for
  639. X.UX
  640. Xsecurity to improve on a global scale, we will also require pressure on
  641. Xthe vendors, so that programs are written correctly from the beginning.
  642. END_OF_FILE
  643. if test 20032 -ne `wc -c <'Docs/README.ms'`; then
  644.     echo shar: \"'Docs/README.ms'\" unpacked with wrong size!
  645. fi
  646. # end of 'Docs/README.ms'
  647. fi
  648. if test -f 'Sources/crack-fcrypt.c' -a "${1}" != "-c" ; then 
  649.   echo shar: Will not clobber existing file \"'Sources/crack-fcrypt.c'\"
  650. else
  651. echo shar: Extracting \"'Sources/crack-fcrypt.c'\" \(24641 characters\)
  652. sed "s/^X//" >'Sources/crack-fcrypt.c' <<'END_OF_FILE'
  653. X/*
  654. X * This program is copyright (c) Alec Muffett 1991 except for certain
  655. X * portions of code ("crack-fcrypt.c") copyright (c) Robert Baldwin, Icarus
  656. X * Sparry and Alec Muffett.  The author(s) disclaims all responsibility or
  657. X * liability with respect to it's usage or its effect upon hardware or
  658. X * computer systems.  This software is in the public domain and is freely
  659. X * redistributable PROVIDED that this notice remains intact.
  660. X */
  661. X
  662. X/*
  663. X * Misc defs for the fast password transform optimisations.
  664. X */
  665. X
  666. X#include "crack.h"        /* contains switches - AEM */
  667. X
  668. X/*
  669. X * Rename the types for greater convenience ? - This is from original code.
  670. X */
  671. X#define    reg    register
  672. X#define    uns    unsigned
  673. X#define unsb    uns char
  674. X#define    unsl    uns long
  675. X
  676. X/*
  677. X * Types for the different ways to represent DES bit patterns.  Bits are
  678. X * always right justified within fields.  Bits which have lower indices in
  679. X * the NBS spec are stored in the vax bits with less significance (e.g., Bit
  680. X * 1 of NBS spec is stored in the bit with weight 2 ** 0 to the Vax.
  681. X */
  682. X
  683. X#define    obpb1    unsb        /* One bit per byte. */
  684. X#define sbpb6    unsb        /* Six bits per byte, 6 held. */
  685. X#define sbpb6R    unsb        /* Six bits per byte Reversed order, 6 held. */
  686. X#define    sbpb24    unsl        /* Six bits per byte, 24 held. */
  687. X#define    ebpb24    unsl        /* Eight bits per bit, 24 held. */
  688. X#define    fbpb4    unsb        /* Four bits per byte, 4 held. */
  689. X#define    fbpb4R    unsb        /* Four bits per byte Reversed order, 4 held. */
  690. X
  691. X/*
  692. X * The operation (6 * x) is often better optimised as this (for really
  693. X * braindead compilers) - AEM
  694. X */
  695. X
  696. X#ifdef BRAINDEAD6
  697. X#define SIX_TIMES(exprn)        (((exprn) << 2) + ((exprn) << 1))
  698. X#else
  699. X#define SIX_TIMES(exprn)        (6 * (exprn))
  700. X#endif                /* BRAINDEAD6 */
  701. X
  702. X/*
  703. X * Data segment gathered into one place - AEM
  704. X */
  705. X
  706. X/* Try to keep this stuff long aligned - AEM */
  707. Xstatic char iobuf[16];
  708. Xstatic obpb1 L[32], R[32];
  709. Xstatic obpb1 crypt_block[72];    /* 72 is next multiple of 8 bytes after 66 */
  710. Xstatic sbpb24 KS[32];
  711. Xstatic sbpb24 S0H[64], S1H[64], S2H[64], S3H[64];
  712. Xstatic sbpb24 S4H[64], S5H[64], S6H[64], S7H[64];
  713. Xstatic sbpb24 S0L[64], S1L[64], S2L[64], S3L[64];
  714. Xstatic sbpb24 S4L[64], S5L[64], S6L[64], S7L[64];
  715. Xstatic sbpb24 out96[4];
  716. X
  717. X/*
  718. X * These used to be rather slow and frequently used functions - AEM
  719. X */
  720. X
  721. X#define TF_TO_SIXBIT(tf) \
  722. X    (sbpb24)((tf & 077L) | \
  723. X        ((tf & 07700L) << 2) | \
  724. X        ((tf & 0770000L) << 4) | \
  725. X        ((tf & 077000000L) << 6))
  726. X
  727. X#define SIXBIT_TO_TF(sb) \
  728. X    (ebpb24)((sb & 0x3fL) | \
  729. X        ((sb & 0x3f00L) >> 2) | \
  730. X        ((sb & 0x3f0000L) >> 4) | \
  731. X        ((sb & 0x3f000000L) >> 6))
  732. X/*
  733. X * Start of the real thing
  734. X */
  735. X
  736. Xvoid
  737. XtoBA64 (quarters /* , crypt_block */ )
  738. X    reg sbpb24 *quarters;
  739. X{
  740. X    static unsb UnDoE[] =
  741. X    {
  742. X    1, 2, 3, 4, 7, 8, 9, 10,
  743. X    13, 14, 15, 16, 19, 20, 21, 22,
  744. X    25, 26, 27, 28, 31, 32, 33, 34,
  745. X    37, 38, 39, 40, 43, 44, 45, 46
  746. X    };
  747. X    static unsb FP[] =
  748. X    {
  749. X    39, 7, 47, 15, 55, 23, 63, 31,
  750. X    38, 6, 46, 14, 54, 22, 62, 30,
  751. X    37, 5, 45, 13, 53, 21, 61, 29,
  752. X    36, 4, 44, 12, 52, 20, 60, 28,
  753. X    35, 3, 43, 11, 51, 19, 59, 27,
  754. X    34, 2, 42, 10, 50, 18, 58, 26,
  755. X    33, 1, 41, 9, 49, 17, 57, 25,
  756. X    32, 0, 40, 8, 48, 16, 56, 24,
  757. X    };
  758. X
  759. X    reg i;
  760. X    static obpb1 tmpE[48];
  761. X    reg unsb *onebits48;
  762. X    reg sbpb24 quarter;
  763. X
  764. X    onebits48 = tmpE;
  765. X    quarter = SIXBIT_TO_TF (*quarters);
  766. X    quarters++;
  767. X
  768. X    /*
  769. X     * Testing one bit and setting another may be faster than shifting and
  770. X     * setting - it's certainly not slower - AEM
  771. X     */
  772. X    *onebits48++ = (quarter & 0x000001L) ? 0x01 : 0;
  773. X    *onebits48++ = (quarter & 0x000002L) ? 0x01 : 0;
  774. X    *onebits48++ = (quarter & 0x000004L) ? 0x01 : 0;
  775. X    *onebits48++ = (quarter & 0x000008L) ? 0x01 : 0;
  776. X    *onebits48++ = (quarter & 0x000010L) ? 0x01 : 0;
  777. X    *onebits48++ = (quarter & 0x000020L) ? 0x01 : 0;
  778. X    *onebits48++ = (quarter & 0x000040L) ? 0x01 : 0;
  779. X    *onebits48++ = (quarter & 0x000080L) ? 0x01 : 0;
  780. X    *onebits48++ = (quarter & 0x000100L) ? 0x01 : 0;
  781. X    *onebits48++ = (quarter & 0x000200L) ? 0x01 : 0;
  782. X    *onebits48++ = (quarter & 0x000400L) ? 0x01 : 0;
  783. X    *onebits48++ = (quarter & 0x000800L) ? 0x01 : 0;
  784. X    *onebits48++ = (quarter & 0x001000L) ? 0x01 : 0;
  785. X    *onebits48++ = (quarter & 0x002000L) ? 0x01 : 0;
  786. X    *onebits48++ = (quarter & 0x004000L) ? 0x01 : 0;
  787. X    *onebits48++ = (quarter & 0x008000L) ? 0x01 : 0;
  788. X    *onebits48++ = (quarter & 0x010000L) ? 0x01 : 0;
  789. X    *onebits48++ = (quarter & 0x020000L) ? 0x01 : 0;
  790. X    *onebits48++ = (quarter & 0x040000L) ? 0x01 : 0;
  791. X    *onebits48++ = (quarter & 0x080000L) ? 0x01 : 0;
  792. X    *onebits48++ = (quarter & 0x100000L) ? 0x01 : 0;
  793. X    *onebits48++ = (quarter & 0x200000L) ? 0x01 : 0;
  794. X    *onebits48++ = (quarter & 0x400000L) ? 0x01 : 0;
  795. X    *onebits48++ = (quarter & 0x800000L) ? 0x01 : 0;
  796. X
  797. X    quarter = SIXBIT_TO_TF (*quarters);
  798. X    quarters++;
  799. X
  800. X    *onebits48++ = (quarter & 0x000001L) ? 0x01 : 0;
  801. X    *onebits48++ = (quarter & 0x000002L) ? 0x01 : 0;
  802. X    *onebits48++ = (quarter & 0x000004L) ? 0x01 : 0;
  803. X    *onebits48++ = (quarter & 0x000008L) ? 0x01 : 0;
  804. X    *onebits48++ = (quarter & 0x000010L) ? 0x01 : 0;
  805. X    *onebits48++ = (quarter & 0x000020L) ? 0x01 : 0;
  806. X    *onebits48++ = (quarter & 0x000040L) ? 0x01 : 0;
  807. X    *onebits48++ = (quarter & 0x000080L) ? 0x01 : 0;
  808. X    *onebits48++ = (quarter & 0x000100L) ? 0x01 : 0;
  809. X    *onebits48++ = (quarter & 0x000200L) ? 0x01 : 0;
  810. X    *onebits48++ = (quarter & 0x000400L) ? 0x01 : 0;
  811. X    *onebits48++ = (quarter & 0x000800L) ? 0x01 : 0;
  812. X    *onebits48++ = (quarter & 0x001000L) ? 0x01 : 0;
  813. X    *onebits48++ = (quarter & 0x002000L) ? 0x01 : 0;
  814. X    *onebits48++ = (quarter & 0x004000L) ? 0x01 : 0;
  815. X    *onebits48++ = (quarter & 0x008000L) ? 0x01 : 0;
  816. X    *onebits48++ = (quarter & 0x010000L) ? 0x01 : 0;
  817. X    *onebits48++ = (quarter & 0x020000L) ? 0x01 : 0;
  818. X    *onebits48++ = (quarter & 0x040000L) ? 0x01 : 0;
  819. X    *onebits48++ = (quarter & 0x080000L) ? 0x01 : 0;
  820. X    *onebits48++ = (quarter & 0x100000L) ? 0x01 : 0;
  821. X    *onebits48++ = (quarter & 0x200000L) ? 0x01 : 0;
  822. X    *onebits48++ = (quarter & 0x400000L) ? 0x01 : 0;
  823. X    *onebits48++ = (quarter & 0x800000L) ? 0x01 : 0;
  824. X
  825. X    /* the next loop used to be the call: undoe (tmpE, L); - AEM */
  826. X
  827. X    for (i = 0; i < 32; i++)
  828. X    {
  829. X    L[i] = tmpE[UnDoE[i]];
  830. X    }
  831. X
  832. X    onebits48 = tmpE;
  833. X    quarter = SIXBIT_TO_TF (*quarters);
  834. X    quarters++;
  835. X
  836. X    *onebits48++ = (quarter & 0x000001L) ? 0x01 : 0;
  837. X    *onebits48++ = (quarter & 0x000002L) ? 0x01 : 0;
  838. X    *onebits48++ = (quarter & 0x000004L) ? 0x01 : 0;
  839. X    *onebits48++ = (quarter & 0x000008L) ? 0x01 : 0;
  840. X    *onebits48++ = (quarter & 0x000010L) ? 0x01 : 0;
  841. X    *onebits48++ = (quarter & 0x000020L) ? 0x01 : 0;
  842. X    *onebits48++ = (quarter & 0x000040L) ? 0x01 : 0;
  843. X    *onebits48++ = (quarter & 0x000080L) ? 0x01 : 0;
  844. X    *onebits48++ = (quarter & 0x000100L) ? 0x01 : 0;
  845. X    *onebits48++ = (quarter & 0x000200L) ? 0x01 : 0;
  846. X    *onebits48++ = (quarter & 0x000400L) ? 0x01 : 0;
  847. X    *onebits48++ = (quarter & 0x000800L) ? 0x01 : 0;
  848. X    *onebits48++ = (quarter & 0x001000L) ? 0x01 : 0;
  849. X    *onebits48++ = (quarter & 0x002000L) ? 0x01 : 0;
  850. X    *onebits48++ = (quarter & 0x004000L) ? 0x01 : 0;
  851. X    *onebits48++ = (quarter & 0x008000L) ? 0x01 : 0;
  852. X    *onebits48++ = (quarter & 0x010000L) ? 0x01 : 0;
  853. X    *onebits48++ = (quarter & 0x020000L) ? 0x01 : 0;
  854. X    *onebits48++ = (quarter & 0x040000L) ? 0x01 : 0;
  855. X    *onebits48++ = (quarter & 0x080000L) ? 0x01 : 0;
  856. X    *onebits48++ = (quarter & 0x100000L) ? 0x01 : 0;
  857. X    *onebits48++ = (quarter & 0x200000L) ? 0x01 : 0;
  858. X    *onebits48++ = (quarter & 0x400000L) ? 0x01 : 0;
  859. X    *onebits48++ = (quarter & 0x800000L) ? 0x01 : 0;
  860. X
  861. X    quarter = SIXBIT_TO_TF (*quarters);
  862. X    quarters++;
  863. X
  864. X    *onebits48++ = (quarter & 0x000001L) ? 0x01 : 0;
  865. X    *onebits48++ = (quarter & 0x000002L) ? 0x01 : 0;
  866. X    *onebits48++ = (quarter & 0x000004L) ? 0x01 : 0;
  867. X    *onebits48++ = (quarter & 0x000008L) ? 0x01 : 0;
  868. X    *onebits48++ = (quarter & 0x000010L) ? 0x01 : 0;
  869. X    *onebits48++ = (quarter & 0x000020L) ? 0x01 : 0;
  870. X    *onebits48++ = (quarter & 0x000040L) ? 0x01 : 0;
  871. X    *onebits48++ = (quarter & 0x000080L) ? 0x01 : 0;
  872. X    *onebits48++ = (quarter & 0x000100L) ? 0x01 : 0;
  873. X    *onebits48++ = (quarter & 0x000200L) ? 0x01 : 0;
  874. X    *onebits48++ = (quarter & 0x000400L) ? 0x01 : 0;
  875. X    *onebits48++ = (quarter & 0x000800L) ? 0x01 : 0;
  876. X    *onebits48++ = (quarter & 0x001000L) ? 0x01 : 0;
  877. X    *onebits48++ = (quarter & 0x002000L) ? 0x01 : 0;
  878. X    *onebits48++ = (quarter & 0x004000L) ? 0x01 : 0;
  879. X    *onebits48++ = (quarter & 0x008000L) ? 0x01 : 0;
  880. X    *onebits48++ = (quarter & 0x010000L) ? 0x01 : 0;
  881. X    *onebits48++ = (quarter & 0x020000L) ? 0x01 : 0;
  882. X    *onebits48++ = (quarter & 0x040000L) ? 0x01 : 0;
  883. X    *onebits48++ = (quarter & 0x080000L) ? 0x01 : 0;
  884. X    *onebits48++ = (quarter & 0x100000L) ? 0x01 : 0;
  885. X    *onebits48++ = (quarter & 0x200000L) ? 0x01 : 0;
  886. X    *onebits48++ = (quarter & 0x400000L) ? 0x01 : 0;
  887. X    *onebits48++ = (quarter & 0x800000L) ? 0x01 : 0;
  888. X
  889. X    /* the next loop used to be the call: undoe (tmpE, R); - AEM */
  890. X
  891. X    for (i = 0; i < 32; i++)
  892. X    {
  893. X    R[i] = tmpE[UnDoE[i]];
  894. X    }
  895. X
  896. X    /* the next loop used to be the call: Fperm (crypt_block); - AEM */
  897. X
  898. X    for (i = 0; i < 64; i++)
  899. X    {
  900. X    crypt_block[i] = L[FP[i]];
  901. X    }
  902. X}
  903. X
  904. Xvoid
  905. Xfsetkey ()
  906. X{
  907. X    /*
  908. X     * This used to be utterly horrendous. It still is, but it's much, much,
  909. X     * smaller... AEM.
  910. X     */
  911. X    static unsb KeyToKS[] =
  912. X    {
  913. X    9, 50, 33, 59, 48, 16, 32, 56, 1, 8, 18, 41, 2, 34, 25, 24,
  914. X    43, 57, 58, 0, 35, 26, 17, 40, 21, 27, 38, 53, 36, 3, 46, 29,
  915. X    4, 52, 22, 28, 60, 20, 37, 62, 14, 19, 44, 13, 12, 61, 54, 30,
  916. X    1, 42, 25, 51, 40, 8, 24, 48, 58, 0, 10, 33, 59, 26, 17, 16,
  917. X    35, 49, 50, 57, 56, 18, 9, 32, 13, 19, 30, 45, 28, 62, 38, 21,
  918. X    27, 44, 14, 20, 52, 12, 29, 54, 6, 11, 36, 5, 4, 53, 46, 22,
  919. X    50, 26, 9, 35, 24, 57, 8, 32, 42, 49, 59, 17, 43, 10, 1, 0,
  920. X    48, 33, 34, 41, 40, 2, 58, 16, 60, 3, 14, 29, 12, 46, 22, 5,
  921. X    11, 28, 61, 4, 36, 27, 13, 38, 53, 62, 20, 52, 19, 37, 30, 6,
  922. X    34, 10, 58, 48, 8, 41, 57, 16, 26, 33, 43, 1, 56, 59, 50, 49,
  923. X    32, 17, 18, 25, 24, 51, 42, 0, 44, 54, 61, 13, 27, 30, 6, 52,
  924. X    62, 12, 45, 19, 20, 11, 60, 22, 37, 46, 4, 36, 3, 21, 14, 53,
  925. X    18, 59, 42, 32, 57, 25, 41, 0, 10, 17, 56, 50, 40, 43, 34, 33,
  926. X    16, 1, 2, 9, 8, 35, 26, 49, 28, 38, 45, 60, 11, 14, 53, 36,
  927. X    46, 27, 29, 3, 4, 62, 44, 6, 21, 30, 19, 20, 54, 5, 61, 37,
  928. X    2, 43, 26, 16, 41, 9, 25, 49, 59, 1, 40, 34, 24, 56, 18, 17,
  929. X    0, 50, 51, 58, 57, 48, 10, 33, 12, 22, 29, 44, 62, 61, 37, 20,
  930. X    30, 11, 13, 54, 19, 46, 28, 53, 5, 14, 3, 4, 38, 52, 45, 21,
  931. X    51, 56, 10, 0, 25, 58, 9, 33, 43, 50, 24, 18, 8, 40, 2, 1,
  932. X    49, 34, 35, 42, 41, 32, 59, 17, 27, 6, 13, 28, 46, 45, 21, 4,
  933. X    14, 62, 60, 38, 3, 30, 12, 37, 52, 61, 54, 19, 22, 36, 29, 5,
  934. X    35, 40, 59, 49, 9, 42, 58, 17, 56, 34, 8, 2, 57, 24, 51, 50,
  935. X    33, 18, 48, 26, 25, 16, 43, 1, 11, 53, 60, 12, 30, 29, 5, 19,
  936. X    61, 46, 44, 22, 54, 14, 27, 21, 36, 45, 38, 3, 6, 20, 13, 52,
  937. X    56, 32, 51, 41, 1, 34, 50, 9, 48, 26, 0, 59, 49, 16, 43, 42,
  938. X    25, 10, 40, 18, 17, 8, 35, 58, 3, 45, 52, 4, 22, 21, 60, 11,
  939. X    53, 38, 36, 14, 46, 6, 19, 13, 28, 37, 30, 62, 61, 12, 5, 44,
  940. X    40, 16, 35, 25, 50, 18, 34, 58, 32, 10, 49, 43, 33, 0, 56, 26,
  941. X    9, 59, 24, 2, 1, 57, 48, 42, 54, 29, 36, 19, 6, 5, 44, 62,
  942. X    37, 22, 20, 61, 30, 53, 3, 60, 12, 21, 14, 46, 45, 27, 52, 28,
  943. X    24, 0, 48, 9, 34, 2, 18, 42, 16, 59, 33, 56, 17, 49, 40, 10,
  944. X    58, 43, 8, 51, 50, 41, 32, 26, 38, 13, 20, 3, 53, 52, 28, 46,
  945. X    21, 6, 4, 45, 14, 37, 54, 44, 27, 5, 61, 30, 29, 11, 36, 12,
  946. X    8, 49, 32, 58, 18, 51, 2, 26, 0, 43, 17, 40, 1, 33, 24, 59,
  947. X    42, 56, 57, 35, 34, 25, 16, 10, 22, 60, 4, 54, 37, 36, 12, 30,
  948. X    5, 53, 19, 29, 61, 21, 38, 28, 11, 52, 45, 14, 13, 62, 20, 27,
  949. X    57, 33, 16, 42, 2, 35, 51, 10, 49, 56, 1, 24, 50, 17, 8, 43,
  950. X    26, 40, 41, 48, 18, 9, 0, 59, 6, 44, 19, 38, 21, 20, 27, 14,
  951. X    52, 37, 3, 13, 45, 5, 22, 12, 62, 36, 29, 61, 60, 46, 4, 11,
  952. X    41, 17, 0, 26, 51, 48, 35, 59, 33, 40, 50, 8, 34, 1, 57, 56,
  953. X    10, 24, 25, 32, 2, 58, 49, 43, 53, 28, 3, 22, 5, 4, 11, 61,
  954. X    36, 21, 54, 60, 29, 52, 6, 27, 46, 20, 13, 45, 44, 30, 19, 62,
  955. X    25, 1, 49, 10, 35, 32, 48, 43, 17, 24, 34, 57, 18, 50, 41, 40,
  956. X    59, 8, 9, 16, 51, 42, 33, 56, 37, 12, 54, 6, 52, 19, 62, 45,
  957. X    20, 5, 38, 44, 13, 36, 53, 11, 30, 4, 60, 29, 28, 14, 3, 46,
  958. X    17, 58, 41, 2, 56, 24, 40, 35, 9, 16, 26, 49, 10, 42, 33, 32,
  959. X    51, 0, 1, 8, 43, 34, 25, 48, 29, 4, 46, 61, 44, 11, 54, 37,
  960. X    12, 60, 30, 36, 5, 28, 45, 3, 22, 27, 52, 21, 20, 6, 62, 38
  961. X    };
  962. X
  963. X    reg int i, j, r;
  964. X    reg unsb *k;
  965. X
  966. X    k = KeyToKS;
  967. X
  968. X    for (i = 0; i < 32; i++)    /* loops cache better ? - AEM */
  969. X    {
  970. X    r = 0;
  971. X    for (j = 0; j < 24; j++)
  972. X    {
  973. X        r |= crypt_block[*(k++)] << j;
  974. X    }
  975. X    KS[i] = TF_TO_SIXBIT (r);
  976. X    }
  977. X}
  978. X
  979. Xvoid
  980. Xxform (quarters, saltvalue)
  981. X    sbpb24 *quarters;
  982. X    sbpb24 saltvalue;
  983. X{
  984. X    union
  985. X    {
  986. X    sbpb24 b[2];
  987. X    sbpb6 c[8];
  988. X    } sdata;
  989. X
  990. X#ifdef sun            /* Icarus Sparry, Bath */
  991. X#define STEP --
  992. X#define START &sdata.c[7]
  993. X#define Dl sdata.b[1]
  994. X#define Dh sdata.b[0]
  995. X#else
  996. X#define STEP ++
  997. X#define START &sdata.c[0]
  998. X#define Dl sdata.b[0]
  999. X#define Dh sdata.b[1]
  1000. X#endif
  1001. X    sbpb24 Rl, Rh;
  1002. X    sbpb24 Ll, Lh;
  1003. X
  1004. X    reg int loop;
  1005. X    reg sbpb24 k;
  1006. X    reg sbpb6 *dp;
  1007. X    reg sbpb24 *kp;
  1008. X    reg sbpb24 *kend;
  1009. X
  1010. X    Ll = Lh = Rl = Rh = 0;
  1011. X
  1012. X    kend = &KS[32];
  1013. X
  1014. X    /*
  1015. X     * Thanks to Matt Bishop for this idea... AEM.
  1016. X     */
  1017. X
  1018. X#ifndef FDES_4BYTE
  1019. X#define SIZEFIX        0
  1020. X#define INDIRECT(a,b)     (a)[b]
  1021. X#else
  1022. X#define SIZEFIX        2    /* "n" where 2^n == sizeof(sbpb24) */
  1023. X#define INDIRECT(a,b)     (*((sbpb24 *)(((unsigned char *) a) + (b))))
  1024. X#endif
  1025. X
  1026. X    for (loop = 25; loop-- > 0; /* nothing */ )
  1027. X    {
  1028. X    for (kp = KS; kp < kend; /* nothing */ )
  1029. X    {
  1030. X        k = (Rl ^ Rh) & saltvalue;
  1031. X        Dl = (k ^ Rl ^ *kp++) << SIZEFIX;
  1032. X        Dh = (k ^ Rh ^ *kp++) << SIZEFIX;
  1033. X
  1034. X        /*
  1035. X         * Oddly enough, direct addressing of dp slows things down, as
  1036. X         * well as knackering portability - AEM
  1037. X         */
  1038. X        dp = START;
  1039. X        Lh ^= INDIRECT (S0H, *dp STEP);
  1040. X        Lh ^= INDIRECT (S1H, *dp STEP);
  1041. X        Lh ^= INDIRECT (S2H, *dp STEP);
  1042. X        Lh ^= INDIRECT (S3H, *dp STEP);
  1043. X        Lh ^= INDIRECT (S4H, *dp STEP);
  1044. X        Lh ^= INDIRECT (S5H, *dp STEP);
  1045. X        Lh ^= INDIRECT (S6H, *dp STEP);
  1046. X        Lh ^= INDIRECT (S7H, *dp STEP);
  1047. X
  1048. X        dp = START;
  1049. X        Ll ^= INDIRECT (S0L, *dp STEP);
  1050. X        Ll ^= INDIRECT (S1L, *dp STEP);
  1051. X        Ll ^= INDIRECT (S2L, *dp STEP);
  1052. X        Ll ^= INDIRECT (S3L, *dp STEP);
  1053. X        Ll ^= INDIRECT (S4L, *dp STEP);
  1054. X        Ll ^= INDIRECT (S5L, *dp STEP);
  1055. X        Ll ^= INDIRECT (S6L, *dp STEP);
  1056. X        Ll ^= INDIRECT (S7L, *dp STEP);
  1057. X
  1058. X        k = (Ll ^ Lh) & saltvalue;
  1059. X        Dl = (k ^ Ll ^ *kp++) << SIZEFIX;
  1060. X        Dh = (k ^ Lh ^ *kp++) << SIZEFIX;
  1061. X
  1062. X        dp = START;
  1063. X        Rh ^= INDIRECT (S0H, *dp STEP);
  1064. X        Rh ^= INDIRECT (S1H, *dp STEP);
  1065. X        Rh ^= INDIRECT (S2H, *dp STEP);
  1066. X        Rh ^= INDIRECT (S3H, *dp STEP);
  1067. X        Rh ^= INDIRECT (S4H, *dp STEP);
  1068. X        Rh ^= INDIRECT (S5H, *dp STEP);
  1069. X        Rh ^= INDIRECT (S6H, *dp STEP);
  1070. X        Rh ^= INDIRECT (S7H, *dp STEP);
  1071. X
  1072. X        dp = START;
  1073. X        Rl ^= INDIRECT (S0L, *dp STEP);
  1074. X        Rl ^= INDIRECT (S1L, *dp STEP);
  1075. X        Rl ^= INDIRECT (S2L, *dp STEP);
  1076. X        Rl ^= INDIRECT (S3L, *dp STEP);
  1077. X        Rl ^= INDIRECT (S4L, *dp STEP);
  1078. X        Rl ^= INDIRECT (S5L, *dp STEP);
  1079. X        Rl ^= INDIRECT (S6L, *dp STEP);
  1080. X        Rl ^= INDIRECT (S7L, *dp STEP);
  1081. X    }
  1082. X
  1083. X    Ll ^= Rl;
  1084. X    Lh ^= Rh;
  1085. X    Rl ^= Ll;
  1086. X    Rh ^= Lh;
  1087. X    Ll ^= Rl;
  1088. X    Lh ^= Rh;
  1089. X    }
  1090. X
  1091. X    {
  1092. X    reg sbpb24 *qp;
  1093. X    qp = quarters;
  1094. X    *qp++ = Ll;
  1095. X    *qp++ = Lh;
  1096. X    *qp++ = Rl;
  1097. X    *qp++ = Rh;
  1098. X    }
  1099. X    return;
  1100. X}
  1101. X
  1102. Xchar *
  1103. Xfcrypt (pw, salt)
  1104. X    char *pw;
  1105. X    char *salt;
  1106. X{
  1107. X    /* Table lookups for salts reduce fcrypt() overhead dramatically */
  1108. X    static sbpb24 salt0[] =
  1109. X    {
  1110. X    18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
  1111. X    34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  1112. X    50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1,
  1113. X    2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 5, 6, 7, 8, 9, 10,
  1114. X    11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
  1115. X    27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 32, 33, 34, 35, 36,
  1116. X    37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
  1117. X    53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4,
  1118. X    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  1119. X    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
  1120. X    37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
  1121. X    53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4,
  1122. X    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  1123. X    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
  1124. X    37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
  1125. X    53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4
  1126. X    };
  1127. X    static sbpb24 salt1[] =
  1128. X    {
  1129. X    1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600,
  1130. X    1664, 1728, 1792, 1856, 1920, 1984, 2048, 2112,
  1131. X    2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624,
  1132. X    2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136,
  1133. X    3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648,
  1134. X    3712, 3776, 3840, 3904, 3968, 4032, 0, 64,
  1135. X    128, 192, 256, 320, 384, 448, 512, 576,
  1136. X    640, 704, 320, 384, 448, 512, 576, 640,
  1137. X    704, 768, 832, 896, 960, 1024, 1088, 1152,
  1138. X    1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
  1139. X    1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176,
  1140. X    2240, 2304, 2368, 2048, 2112, 2176, 2240, 2304,
  1141. X    2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816,
  1142. X    2880, 2944, 3008, 3072, 3136, 3200, 3264, 3328,
  1143. X    3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840,
  1144. X    3904, 3968, 4032, 0, 64, 128, 192, 256,
  1145. X    320, 384, 448, 512, 576, 640, 704, 768,
  1146. X    832, 896, 960, 1024, 1088, 1152, 1216, 1280,
  1147. X    1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792,
  1148. X    1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
  1149. X    2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816,
  1150. X    2880, 2944, 3008, 3072, 3136, 3200, 3264, 3328,
  1151. X    3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840,
  1152. X    3904, 3968, 4032, 0, 64, 128, 192, 256,
  1153. X    320, 384, 448, 512, 576, 640, 704, 768,
  1154. X    832, 896, 960, 1024, 1088, 1152, 1216, 1280,
  1155. X    1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792,
  1156. X    1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
  1157. X    2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816,
  1158. X    2880, 2944, 3008, 3072, 3136, 3200, 3264, 3328,
  1159. X    3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840,
  1160. X    3904, 3968, 4032, 0, 64, 128, 192, 256
  1161. X    };
  1162. X
  1163. X    /* final perutation desalting */
  1164. X    static obpb1 final[] =
  1165. X    {
  1166. X    46, 47, 48, 49, 50, 51, 52, 53,
  1167. X    54, 55, 56, 57, 65, 66, 67, 68,
  1168. X    69, 70, 71, 72, 73, 74, 75, 76,
  1169. X    77, 78, 79, 80, 81, 82, 83, 84,
  1170. X    85, 86, 87, 88, 89, 90, 97, 98,
  1171. X    99, 100, 101, 102, 103, 104, 105, 106,
  1172. X    107, 108, 109, 110, 111, 112, 113, 114,
  1173. X    115, 116, 117, 118, 119, 120, 121, 122,
  1174. X    123, 124, 125, 126, 127, 128, 129, 130,
  1175. X    131, 132, 133, 134, 135, 136, 137, 138,
  1176. X    139, 140, 141, 142, 143, 144, 145, 146,
  1177. X    147, 148, 149, 150, 151, 152, 153, 154,
  1178. X    155, 156, 157, 158, 159, 160, 161, 162,
  1179. X    163, 164, 165, 166, 167, 168, 169, 170,
  1180. X    171, 172, 173, 174, 175, 176, 177, 178,
  1181. X    179, 180, 181, 182, 183, 184, 185, 186,
  1182. X    187, 188, 189, 190, 191, 192, 193, 194,
  1183. X    195, 196, 197, 198, 199, 200, 201, 202,
  1184. X    203, 204, 205, 206, 207, 208, 209, 210,
  1185. X    211, 212, 213, 214, 215, 216, 217, 218,
  1186. X    219, 220, 221, 222, 223, 224, 225, 226,
  1187. X    227, 228, 229, 230, 231, 232, 233, 234,
  1188. X    235, 236, 237, 238, 239, 240, 241, 242,
  1189. X    243, 244, 245, 246, 247, 248, 249, 250,
  1190. X    251, 252, 253, 254, 255,
  1191. X    /* Truncate overflow bits at 256 */
  1192. X    0, 1, 2, 3, 4, 5, 6, 7,
  1193. X    8, 9, 10, 11, 12, 13, 14, 15,
  1194. X    16, 17, 18, 19, 20, 21, 22, 23,
  1195. X    24, 25, 26, 27, 28, 29, 30, 31,
  1196. X    32, 33, 34, 35, 36, 37, 38, 39,
  1197. X    40, 41, 42, 43, 44, 45, 46, 47,
  1198. X    48, 49, 50, 51, 52, 53, 54, 55,
  1199. X    56, 57, 58
  1200. X    };
  1201. X
  1202. X    reg int i, j, k;
  1203. X    reg long int *lip;
  1204. X    sbpb24 saltvalue;
  1205. X
  1206. X#if defined(BUILTIN_CLEAR)
  1207. X    lip = (long int *) crypt_block;
  1208. X    for (i = (sizeof (crypt_block) / sizeof (long int)); i > 0; i--)
  1209. X    {
  1210. X    *(lip++) = 0L;
  1211. X    }
  1212. X#elif defined(BZERO)
  1213. X    bzero (crypt_block, 66);
  1214. X#else
  1215. X    for (i = 0; i < 66; i++)
  1216. X    {
  1217. X    crypt_block[i] = '\0';
  1218. X    }
  1219. X#endif
  1220. X
  1221. X    for (i = 0; (k = *pw) && i < 64; pw++)
  1222. X    {
  1223. X    crypt_block[i++] = (k >> 6) & 01;
  1224. X    crypt_block[i++] = (k >> 5) & 01;
  1225. X    crypt_block[i++] = (k >> 4) & 01;
  1226. X    crypt_block[i++] = (k >> 3) & 01;
  1227. X    crypt_block[i++] = (k >> 2) & 01;
  1228. X    crypt_block[i++] = (k >> 1) & 01;
  1229. X    crypt_block[i++] = (k >> 0) & 01;
  1230. X    i++;            /* have to skip one here (parity bit) */
  1231. X    }
  1232. X
  1233. X    fsetkey ( /* crypt_block */ );
  1234. X
  1235. X
  1236. X#if defined(BUILTIN_CLEAR)
  1237. X    lip = (long int *) crypt_block;
  1238. X    for (i = (sizeof (crypt_block) / sizeof (long int)); i > 0; i--)
  1239. X    {
  1240. X    *(lip++) = 0L;
  1241. X    }
  1242. X#elif defined(BZERO)
  1243. X    bzero (crypt_block, 66);
  1244. X#else
  1245. X    for (i = 0; i < 66; i++)
  1246. X    {
  1247. X    crypt_block[i] = '\0';
  1248. X    }
  1249. X#endif
  1250. X
  1251. X    iobuf[0] = salt[0];
  1252. X    iobuf[1] = salt[1];
  1253. X
  1254. X    saltvalue = salt0[iobuf[0]] | salt1[iobuf[1]];
  1255. X    saltvalue = TF_TO_SIXBIT (saltvalue);
  1256. X
  1257. X    xform (out96, saltvalue);
  1258. X
  1259. X    toBA64 (out96 /* , crypt_block */ );
  1260. X
  1261. X    for (i = 0; i < 11; i++)
  1262. X    {
  1263. X    k = 0;
  1264. X
  1265. X    for (j = 0; j < 6; j++)
  1266. X    {
  1267. X        k = (k << 1) | crypt_block[SIX_TIMES (i) + j];
  1268. X    }
  1269. X    iobuf[i + 2] = final[k];
  1270. X    }
  1271. X
  1272. X    iobuf[i + 2] = 0;
  1273. X
  1274. X    if (iobuf[1] == 0)
  1275. X    {
  1276. X    iobuf[1] = iobuf[0];
  1277. X    }
  1278. X    return (iobuf);
  1279. X}
  1280. X/********* INITIALISATION ROUTINES *********/
  1281. X
  1282. Xfbpb4
  1283. XlookupS (tableno, t6bits)
  1284. X    unsl tableno;
  1285. X    sbpb6R t6bits;
  1286. X{
  1287. X    static fbpb4R S[8][64] =
  1288. X    {
  1289. X    14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
  1290. X    0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
  1291. X    4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
  1292. X    15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
  1293. X
  1294. X    15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
  1295. X    3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
  1296. X    0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
  1297. X    13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
  1298. X
  1299. X    10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
  1300. X    13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
  1301. X    13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
  1302. X    1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
  1303. X
  1304. X    7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
  1305. X    13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
  1306. X    10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
  1307. X    3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
  1308. X
  1309. X    2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
  1310. X    14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
  1311. X    4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
  1312. X    11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
  1313. X
  1314. X    12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
  1315. X    10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
  1316. X    9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
  1317. X    4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
  1318. X
  1319. X    4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
  1320. X    13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
  1321. X    1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
  1322. X    6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
  1323. X
  1324. X    13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
  1325. X    1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
  1326. X    7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
  1327. X    2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
  1328. X    };
  1329. X    sbpb6 fixed6bits;
  1330. X    fbpb4R r;
  1331. X    fbpb4 fixedr;
  1332. X
  1333. X    fixed6bits = (((t6bits >> 0) & 01) << 5) +
  1334. X    (((t6bits >> 1) & 01) << 3) +
  1335. X    (((t6bits >> 2) & 01) << 2) +
  1336. X    (((t6bits >> 3) & 01) << 1) +
  1337. X    (((t6bits >> 4) & 01) << 0) +
  1338. X    (((t6bits >> 5) & 01) << 4);
  1339. X
  1340. X    r = S[tableno][fixed6bits];
  1341. X
  1342. X    fixedr = (((r >> 3) & 01) << 0) +
  1343. X    (((r >> 2) & 01) << 1) +
  1344. X    (((r >> 1) & 01) << 2) +
  1345. X    (((r >> 0) & 01) << 3);
  1346. X
  1347. X    return (fixedr);
  1348. X}
  1349. X
  1350. Xvoid
  1351. Xinit (tableno, lowptr, highptr)
  1352. X    unsl tableno;
  1353. X    sbpb24 *lowptr, *highptr;
  1354. X{
  1355. X
  1356. X    static unsb P[] =
  1357. X    {
  1358. X    15, 6, 19, 20,
  1359. X    28, 11, 27, 16,
  1360. X    0, 14, 22, 25,
  1361. X    4, 17, 30, 9,
  1362. X    1, 7, 23, 13,
  1363. X    31, 26, 2, 8,
  1364. X    18, 12, 29, 5,
  1365. X    21, 10, 3, 24,
  1366. X    };
  1367. X
  1368. X    static unsb E[] =
  1369. X    {
  1370. X    31, 0, 1, 2, 3, 4,
  1371. X    3, 4, 5, 6, 7, 8,
  1372. X    7, 8, 9, 10, 11, 12,
  1373. X    11, 12, 13, 14, 15, 16,
  1374. X    15, 16, 17, 18, 19, 20,
  1375. X    19, 20, 21, 22, 23, 24,
  1376. X    23, 24, 25, 26, 27, 28,
  1377. X    27, 28, 29, 30, 31, 0,
  1378. X    };
  1379. X
  1380. X    static obpb1 tmp32[32];
  1381. X    static obpb1 tmpP32[32];
  1382. X    static obpb1 tmpE[32];
  1383. X
  1384. X    int j, k, i;
  1385. X    int tablenoX4;
  1386. X    reg sbpb24 spare24;
  1387. X
  1388. X    tablenoX4 = tableno * 4;
  1389. X
  1390. X    for (j = 0; j < 64; j++)
  1391. X    {
  1392. X    k = lookupS (tableno, j);
  1393. X
  1394. X    for (i = 0; i < 32; i++)
  1395. X    {
  1396. X        tmp32[i] = 0;
  1397. X    }
  1398. X    for (i = 0; i < 4; i++)
  1399. X    {
  1400. X        tmp32[tablenoX4 + i] = (k >> i) & 01;
  1401. X    }
  1402. X    for (i = 0; i < 32; i++)
  1403. X    {
  1404. X        tmpP32[i] = tmp32[P[i]];
  1405. X    }
  1406. X    for (i = 0; i < 48; i++)
  1407. X    {
  1408. X        tmpE[i] = tmpP32[E[i]];
  1409. X    }
  1410. X
  1411. X    lowptr[j] = 0;
  1412. X    highptr[j] = 0;
  1413. X
  1414. X    for (i = 0; i < 24; i++)
  1415. X    {
  1416. X        lowptr[j] |= tmpE[i] << i;
  1417. X    }
  1418. X    for (k = 0, i = 24; i < 48; i++, k++)
  1419. X    {
  1420. X        highptr[j] |= tmpE[i] << k;
  1421. X    }
  1422. X
  1423. X    spare24 = lowptr[j];    /* to allow for macro expansion */
  1424. X    lowptr[j] = TF_TO_SIXBIT (spare24);
  1425. X    spare24 = highptr[j];    /* to allow for macro expansion */
  1426. X    highptr[j] = TF_TO_SIXBIT (spare24);
  1427. X    }
  1428. X}
  1429. Xinit_des ()
  1430. X{
  1431. X    init (0, S0L, S0H);
  1432. X    init (1, S1L, S1H);
  1433. X    init (2, S2L, S2H);
  1434. X    init (3, S3L, S3H);
  1435. X    init (4, S4L, S4H);
  1436. X    init (5, S5L, S5H);
  1437. X    init (6, S6L, S6H);
  1438. X    init (7, S7L, S7H);
  1439. X}
  1440. END_OF_FILE
  1441. if test 24641 -ne `wc -c <'Sources/crack-fcrypt.c'`; then
  1442.     echo shar: \"'Sources/crack-fcrypt.c'\" unpacked with wrong size!
  1443. fi
  1444. # end of 'Sources/crack-fcrypt.c'
  1445. fi
  1446. echo shar: End of archive 3 \(of 4\).
  1447. cp /dev/null ark3isdone
  1448. MISSING=""
  1449. for I in 1 2 3 4 ; do
  1450.     if test ! -f ark${I}isdone ; then
  1451.     MISSING="${MISSING} ${I}"
  1452.     fi
  1453. done
  1454. if test "${MISSING}" = "" ; then
  1455.     echo You have unpacked all 4 archives.
  1456.     rm -f ark[1-9]isdone
  1457. else
  1458.     echo You still need to unpack the following archives:
  1459.     echo "        " ${MISSING}
  1460. fi
  1461. ##  End of shell archive.
  1462. exit 0
  1463. exit 0 # Just in case...
  1464.