home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3890 < prev    next >
Encoding:
Internet Message Format  |  1991-08-23  |  47.1 KB

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