home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume25
/
crack
/
part03
< prev
next >
Wrap
Text File
|
1991-11-03
|
43KB
|
1,247 lines
Newsgroups: comp.sources.misc,alt.security
From: aem@aberystwyth.ac.uk (Alec Muffett)
Subject: v25i007: crack - The Password Cracker, version 4.0a, Part03/05
Message-ID: <1991Nov3.231544.10268@sparky.imd.sterling.com>
X-Md4-Signature: d19cdf7210b74f434b26da0b4f1aa413
Date: Sun, 3 Nov 1991 23:15:44 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: aem@aber.ac.uk (Alec David Muffett)
Posting-number: Volume 25, Issue 7
Archive-name: crack/part03
Environment: UNIX
Supersedes: crack: Volume 23, Issue 1-5
#! /bin/sh
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 3 (of 5)."
# Contents: APPENDIX.4.0 Sources/crack-fcrypt.c
# Wrapped by aem@aberda on Thu Oct 24 11:14:43 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'APPENDIX.4.0' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'APPENDIX.4.0'\"
else
echo shar: Extracting \"'APPENDIX.4.0'\" \(16140 characters\)
sed "s/^X//" >'APPENDIX.4.0' <<'END_OF_FILE'
XAPPENDIX FILE FOR VERSION 4.0 of Crack. By Alec Muffett, 7th Oct 1991
X**********************************************************************
XThis is the latest version of Crack, The Sensible Password Cracker.
X
XThere have been a LOT of changes since version 3.*, first and foremost,
Xthere is NO DICTIONARY PREPROCESSOR. This is part of a drive during
Xre-writing the code to move as much as possible of the configuration
Xgumph out of the central code and into the Scripts directory.
X
XAll the manipulations which are carried out on the dictionary are
Xcontrolled by external files, so that the user can configure the program
Xto permute and unique the dictionary on the fly, saving vast amounts of
Xfilestore for a small time tradeoff.
X
XIf you really want to make a dictionary pass of capitalised reversed
Xwords containing the letter "Q" with a semicolon appended, feel free!
XThe rule is:-
X cr/Q$;
X
XThis is further detailed in the README file. The extra flexibility
Xgenerated is worth the slight loss in efficiency,
X
XOther changes in attitude and programming style: Crack is now written
Xwith most of it's features hardwired in; eg: Feedback mode is no longer
Xoptional, Crack output files ALWAYS print their guesses, and so on.
X
XThis is partly due to laziness, and partly due to the complexity of the
Xcode. It's simpler if I assume that users don't want to go around
Xcrippling the code before running it.
X
XAlso, I assume that certin features are supplied with your c-compiler
Xtoo. You will need a qsort() function as well as a getopt() function to
Xrun v4.0, but these are pretty common nowadays. If not, complain to
Xyour vendor or pull one from the public domain.
X
XAlso, I've tried (with a lot of external help: thanks to cip_maz) to get
XCrack working on 16 bit machines. It may work... 8-)
X
XCrack now can scan .plan/.project/.signature files for information...
XIt only checks the first 1Kb of each file... I consider this to be
Xenough, because, as I well know, some .plan files get a bit bigger than
Xthat. (If you don't know what I'm talking about, pull a copy of ASP
Xfrom your local comp.sources.misc archive. My big .plan is 2.6Mb)
X
XFinally, I'm providing with this version a "terms of usage" file, which
Xdetails what I would like people to do or not do with my code. I've
Xworked bloody hard on this project, partly in hope that it will scare
Xthe commercial world into doing things for unix security amongst the
Xunix community. Two BIG multinationals have already contacted me about
Xthis code, but mostly because it's done horrible things to their
Xinternal network security. I'd like to see them implement something for
Xthe users, too...
X
XI DO intend to keep Crack up to date with development work, but my
Xfuture on the net is looking a little shaky at the moment. Hang in
Xthere - if you get no immediate reply on EMailing me, I'll get back to
Xyou eventually. It does seem that Crack v4.0 has gone just about as far
Xas it can without being too silly or inefficient, so I am going to have
Xto consider VERY CAREFULLY about where it goes from here on in.
X
X in peaceful paranoia,
X yours sincerely,
X
X alec muffett (with TWO T's !)
X***********************************************************************
XThere now follows any information that is still pertinent from previous
XAPPENDIX files
X***********************************************************************
X
XSeveral people have asked me why I don't write Crack so that it
Xdistributes dictionaries over the network and hacks the same password
Xfile on each machine, as opposed to spreading users over the network and
Xusing the same dictionaries.
X
XThere are several reasons for this, which I will outline.
X
XThe reasoning that spreading the dictionaries over the network is faster
Xis correct in the case of cracking the passwords of ONE user - it is
Xmost efficient to run different dictionaries on him on several machines,
Xand you will break his password eventually.
X
XScaling this by a factor of 'n' users causes problems. Firstly, if a
Xmachine guesses one persons password, it must inform all others on the
Xnetwork not to waste time cracking him, but to get on with the other
Xusers. This is difficult and nasty.
X
XSecondly, it is not what Crack was designed to do. The name "Crack" is
Xactually a misnomer - Crack really ought to be called "Passwdcheck" or
Xsomething similar, but such names lack sex appeal.
X
XCrack is not a program designed to break the password of every user in
Xthe file. Rather, it is designed to find weak passwords in the file, by
Xattacking those sorts of bad passwords which are most likely to be used,
Xin the order in which they would most easily be found (ie: are most
Xlikely to be used by a moronic user).
X
XCrack is not designed to break user passwords; it is designed to break
Xpassword files. This is a subtle but important distinction.
X
XIf you want to break into a safe, you do not take a hammer at every bit
Xof it in turn; instead, first you try some simple combinations, then you
Xtry blowing the hinges off, then you get out an acetylene torch and go
Xfor the bolt. If that doesnt work, THEN you start on the walls. You go
Xfor the bits which are most likely to be weak first.
X
XConsider a password file with 'n' users in it. Say that your ordinary,
Xserial password cracker uses a dictionary of 1000 words, and tries each
Xword 6 ways (upper/lower/mixed case, permuted with forwards/backwards)
X
XAlso consider that out of that 1000 users, only one (the last one) has a
Xguessable password - "fred".
X
XAlso say that it takes time 'T' seconds to encrypt a word.
X
XIf you use the "try each user in turn" method, like the COPS password
Xcracker, you will have to wait for a time:-
X
X 999 users * 1000 words * 6 ways * T = 5994000 T seconds
X
Xbefore you get to that last user. Spreading this load around on a
Xnetwork only alleviates the number of words to be searched (divides them
Xby the number of machines you are working on).
X
XThus, if you use 10 machines, the machine which will guess "fred" will
Xget to that last user in:-
X
X 999 * (1000 / 10) * 6 ways = 599400 T seconds.
X
XAlternatively you can try it the Crack way - "fred" is a word which
Xappears in a forwards dictionary. You will only wait:-
X
X 999 users * 1000 words * 1st way * T = 999000 T seconds
X
Xto get to that user. Now split the users across 10 machines (for
Xsimplicity, as outlined above):-
X
X (999 / 10) users * 1000 words * 1st way = 99900 T seconds
X
XTo get to his password, in ONLY 17% of the time taken by networking
Xusing the serial cracking method. This is only a boundary case, but I
Xhope I have illustrated the concept.
X
X********
X
XCrack has several other optimisations because of its structured password
Xguesses. The figures below are entirely empirical, but I reckon that
Xthey're as good as any:
X
XThe first pass that Crack makes is over the user data user information
Xgleaned from the users' password field. In my test file, this gets
Xabout 3% of the passwords (out of a total of 11% guessed). This pass
Xalso completes the quickest of all, working as it does from a very small
Xamount of data, but one which is very frequently used for passwords.
X
XThe first sweep of the second pass, consisting of lowercase dictionary
Xwords, gets about another 5% of the passwords. This means that, for our
X1150 users, we have now cracked a cumulative total of 91 accounts. The
Xlength of the first sweep depends on how much CPU and how many
Xdictionaries I supply, but using the Ultrix /usr/dict/words and my
Xbad_pws.dat, over 4 CPUs, it doesn't take much more that a couple of
Xhours.
X
XFor the further sweeps, the percentages cracked per sweep tail off, 2%,
X1%, 0.5%... But they are the people with fairly exotic passwords, and
Xit's only common sense that that they will take some time to crack.
X
X********
X
XThere is one more major optimisation that I haven't mentioned. Because
Xof the way the UNIX crypt() algorithm works, each encryption is "salted"
Xwith a two letter sequence which is stored as the first two characters
Xof the encrypted password. This salting means that the word "fred" can
Xbe encrypted and appear in a password file in (literally) thousands of
Xdifferent ways - so long as each encryption has a different salt.
X
XHence, it makes sense to do things in this manner:
X
X1) sort and group the input data by encryption salt.
X2) for each different groups' encryption salt
X * get a dictionary word
X * encrypt it using that salt (This is the time consuming bit)
X * compare the encryption with each member of the group with that salt
X * if it matches, you have guessed that users password.
X
XThis knocks (empirical guesswork time again) up to one third of the
Xdictionary encryptions off - thus saving you 0.3 of the time all the
Xdictionary sweeps would ordinarily take. You can work out this figure
Xyourself: Crack gives this statistic when it says
X
X pwc: Loaded 'n' password entries into 'm' salted lines.
X
Xso you can work out the percentage of users who have the same salt:-
X
X x = (m / n) * 100
X
Xand hence the percentage of encryption time that you save = (100 - x).
X
X********
X
XI was listening to the REM album 'Green' on the way back from the
XCropredy folk festival, whilst thinking over things to do to Crack, and
XI was struck (not for the first time) by the words of the first verse to
X'World Leader Pretend':-
X
X I sit at my table, and wage war upon myself.
X It seems like it's all, it's all for nothing.
X I know the barricades, and I know the mortar in the wall
X I recognise the weapons, I use them well.
X
X This is my mistake, let me make it good,
X I raised the wall, and I will be the one to knock it down...
X
X- writing password cracking programs gets to you after a bit.
X
X********
X
XSome people have asked me how to generate safe passwords. This, sadly,
Xhas become a religious issue, and there are now, on USENET, several
Xvociferous "password geeks" who will say "my method is the best", in the
Xsame way that some mathematicians will try to compare so-called "random
Xnumber generating algorithms". Such statements are pointless. I'm
Xsorry for adding to the confusion, but I must say that I think they are
Xwrong.
X
XOkay, so I am a security fatalist and a security philosopher, but I am
Xnot going to give and hard and fast answers; rather, I'd like to make
Xsome points and recommendations to the people out there. Security isn't
Xa tangible thing, it is applied psychology.
X
XThe whole point of a password is to prevent people accessing your
Xsystem, getting into it from outside. Once someone is inside your
Xsystem, assuming that they have the relevant knowledge of your O/S, it
Xis safest to assume that anyone can get to be 'superuser'. Your only
Xsecurity once someone is on your system is called "security by
Xobscurity". If your user has sufficient knowledge, you've "had it".
X
XThe question isn't "How secure can my system be made?".
X
XThe question really should be, "How much do I care, how much can I trust?".
X
XA system can be perfectly secure without any passwords at all, so long
Xas it is in an environment of people who recognise its purpose and
Xdepend on it. I say this after having had acounts on several 'public'
Xmachines, which could have been taken to bits by any competent Unix
Xperson, but were largely safe - because when someone worked out who did
Xanything nasty, the culprit was ostracised from the community. There
X_is_ a caveat to this, however.
X
XThe problem is the sort of people who go around the world 'collecting'
Xcomputer accounts and breaking machines, those who have either a
Xchildish mentality or an ulterior motive.
X
XThe former are like the little boys who go around breaking windows and
Xvandalising things 'for kicks'. They are the ones who see every
Xpassword file as a "NO ENTRY" sign, and therefore, driven by what they
Xthink is anarchy and fun, they break in and smash the place up. Tell
Xthem that they are behaving like children, and they will behave moreso.
X
XThe latter are driven by personal motives or money. Their reasons are
Xtoo complex for me to analyse here.
X
XThe 'babyish' hackers need a lesson (which I hope that eventually they
Xlearn) that true anarchy is for the general good, and is best achieved
Xby fiat amongst the community. USENET is a good example - there is a
Xlot of petty bickering and arguing, but an incredible amount of good
Xcomes out of it. It is anarchy that the old greek philosophers would
Xhave approved of.
X
XWhat I am trying to say is that, when I say that if someone gets into
Xyour system, you've "had it", you should consider whether there is
Xanything to have "had" in the first place. There is no point in getting
Xyourself paranoid over security - if you do, you'll lose out. Don't be
Xtoo paranoid. Be SENSIBLE instead, and secure your system according to
Xit's needs, and not according to some 'holy bible' of absolute security.
X
XIf someone gets into your system, you find out how they did it, patch
Xthe hole, check for back doors, brush yourself off, and start again.
XIt's not the end of the world.
X
XWhat this statement doesn't address (yet) is the needs of system
Xmanagers who have a REAL need for security - be it corporate data or
Xresearch work - on their system. As I have said before, most O/S's have
Xgaping holes in them that cannot be entirely filled, and so the crackers
Xmust be stopped on the doorstep. At the password login.
X
XPeople who say that they have a way of generating safe passwords are
Xmisinformed, IMHO. Saying that the password "wyufwqpl" is secure is as
Xmeaningful as saying that the number "4" is random. Password security,
Xlike any other form of computer security, is not absolute, but should
Xbe taken in context.
X
XYou can't say that a certain method will provide secure, random
Xpasswords, because, in defining an algorithm to create these passwords,
Xyou will use only a subset of all the possible passwords that could ever
Xexist. You have shrunk the 'search space' for the passwords.
X
XSomeone merely has to write a password cracker which will search this
Xsmall subset of passwords, in order to break your system. Passwords
Xgenerated by any algorithm, human or computer based, are merly
Xpseudo-secure, in the same way that numbers can be pseudo-random. For
Xillustration of this aspect of password security, read the document
X"Password Security, A Case History" by Morris and Thompson.
X
XThere is an incredibly large set of possible passwords in the world, and
Xthe best approach toward choosing a password is not to try to find a way
Xto generate 'secure' passwords - there are no such things - but rather
Xyou should learn to choose passwords which are not easily searched for.
XPasswords which are out of the 'search space' of most password crackers
Xlike 'Crack'.
X
XRead the Crack documentation. See what sort of things other programs
Xlike Crack would search for. Think of some yourself. I am not going to
Xspecifically mention methods, you should really work something out for
Xyourself.
X
XAt the bottom line, the password "fred" is just as secure (random) as
Xthe password "blurflpox"; the only problem is that "fred" is in a more
Xeasily searched part of the "password space".
X
XBoth of these passwords are more easily found than "Dxk&2+15^N" however.
XNow you must ask yourself if you can cope with remembering "Dxk&2+15^N".
X
X8-)
X
X********
X
XI'd like to thank Chris Samuel & Piercarlo (Peter) Grandi for all their
Xhelp in beta-testing early versions of Crack, and in Peter's case
Xespecially, for dropping me into the deep end of troff. Die, you
Xbastard. 8->
X
XI'd also like to thank Chris Myers, Randal Schwartz, Chris Lewis,
XM.Maclaren@bath, and Brian Tompsett (bct@uk.ac.hull.cs), for pointing me
Xto the now famous v3.2 bug, and for numerous suggestions and patches,
Xnot to mention the enormous amount of debugging information he's sent me
Xabout Crack v3.3. To him should go the prize for "Most Vociferous Beta
XTester".
X
XAnd finally, to my girlfriend Gilly, for her occasional large doses of
Xsanity. 8-)
X - alec
X--
XINET: aem@aber.ac.uk JANET: aem@uk.ac.aber BITNET: aem%aber@ukacrl
XUUCP: ...!mcsun!ukc!aber!aem ARPA: aem%uk.ac.aber@nsfnet-relay.ac.uk
XSNAIL: Alec Muffett, Computer Unit, Llandinam UCW, Aberystwyth, UK, SY23 3DB
X
END_OF_FILE
if test 16140 -ne `wc -c <'APPENDIX.4.0'`; then
echo shar: \"'APPENDIX.4.0'\" unpacked with wrong size!
fi
# end of 'APPENDIX.4.0'
fi
if test -f 'Sources/crack-fcrypt.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Sources/crack-fcrypt.c'\"
else
echo shar: Extracting \"'Sources/crack-fcrypt.c'\" \(22754 characters\)
sed "s/^X//" >'Sources/crack-fcrypt.c' <<'END_OF_FILE'
X/*
X * This program is copyright Alec Muffett 1991 except for some portions of
X * code in "crack-fcrypt.c" which are copyright Robert Baldwin, Icarus
X * Sparry and Alec Muffett. The author(s) disclaims all responsibility or
X * liability with respect to it's usage or its effect upon hardware or
X * computer systems, and maintain copyright as set out in the "LICENCE"
X * document which accompanies distributions of Crack v4.0 and upwards.
X */
X
X/*
X * Misc defs for the fast password transform optimisations.
X */
X
X#include "crack.h"
X
X/*
X * Data segment gathered into one place, try to keep this stuff long aligned
X * - AEM
X */
X
Xstatic char iobuf[16];
Xstatic obpb1 crypt_block[72]; /* 72 is next multiple of 8 bytes after 66 */
Xstatic sbpb24 KS[32];
Xstatic sbpb24 S0H[64], S1H[64], S2H[64], S3H[64];
Xstatic sbpb24 S4H[64], S5H[64], S6H[64], S7H[64];
Xstatic sbpb24 S0L[64], S1L[64], S2L[64], S3L[64];
Xstatic sbpb24 S4L[64], S5L[64], S6L[64], S7L[64];
Xstatic sbpb24 out96[4];
X
X/*
X * Start of the real thing
X */
X
Xvoid
Xfsetkey ()
X{
X /*
X * This used to be utterly horrendous. It still is, but it's much, much,
X * smaller... (and quite a bit faster...) - AEM
X */
X static unsb KeyToKS[] =
X {
X 9, 50, 33, 59, 48, 16, 32, 56, 1, 8, 18, 41, 2, 34, 25, 24,
X 43, 57, 58, 0, 35, 26, 17, 40, 21, 27, 38, 53, 36, 3, 46, 29,
X 4, 52, 22, 28, 60, 20, 37, 62, 14, 19, 44, 13, 12, 61, 54, 30,
X 1, 42, 25, 51, 40, 8, 24, 48, 58, 0, 10, 33, 59, 26, 17, 16,
X 35, 49, 50, 57, 56, 18, 9, 32, 13, 19, 30, 45, 28, 62, 38, 21,
X 27, 44, 14, 20, 52, 12, 29, 54, 6, 11, 36, 5, 4, 53, 46, 22,
X 50, 26, 9, 35, 24, 57, 8, 32, 42, 49, 59, 17, 43, 10, 1, 0,
X 48, 33, 34, 41, 40, 2, 58, 16, 60, 3, 14, 29, 12, 46, 22, 5,
X 11, 28, 61, 4, 36, 27, 13, 38, 53, 62, 20, 52, 19, 37, 30, 6,
X 34, 10, 58, 48, 8, 41, 57, 16, 26, 33, 43, 1, 56, 59, 50, 49,
X 32, 17, 18, 25, 24, 51, 42, 0, 44, 54, 61, 13, 27, 30, 6, 52,
X 62, 12, 45, 19, 20, 11, 60, 22, 37, 46, 4, 36, 3, 21, 14, 53,
X 18, 59, 42, 32, 57, 25, 41, 0, 10, 17, 56, 50, 40, 43, 34, 33,
X 16, 1, 2, 9, 8, 35, 26, 49, 28, 38, 45, 60, 11, 14, 53, 36,
X 46, 27, 29, 3, 4, 62, 44, 6, 21, 30, 19, 20, 54, 5, 61, 37,
X 2, 43, 26, 16, 41, 9, 25, 49, 59, 1, 40, 34, 24, 56, 18, 17,
X 0, 50, 51, 58, 57, 48, 10, 33, 12, 22, 29, 44, 62, 61, 37, 20,
X 30, 11, 13, 54, 19, 46, 28, 53, 5, 14, 3, 4, 38, 52, 45, 21,
X 51, 56, 10, 0, 25, 58, 9, 33, 43, 50, 24, 18, 8, 40, 2, 1,
X 49, 34, 35, 42, 41, 32, 59, 17, 27, 6, 13, 28, 46, 45, 21, 4,
X 14, 62, 60, 38, 3, 30, 12, 37, 52, 61, 54, 19, 22, 36, 29, 5,
X 35, 40, 59, 49, 9, 42, 58, 17, 56, 34, 8, 2, 57, 24, 51, 50,
X 33, 18, 48, 26, 25, 16, 43, 1, 11, 53, 60, 12, 30, 29, 5, 19,
X 61, 46, 44, 22, 54, 14, 27, 21, 36, 45, 38, 3, 6, 20, 13, 52,
X 56, 32, 51, 41, 1, 34, 50, 9, 48, 26, 0, 59, 49, 16, 43, 42,
X 25, 10, 40, 18, 17, 8, 35, 58, 3, 45, 52, 4, 22, 21, 60, 11,
X 53, 38, 36, 14, 46, 6, 19, 13, 28, 37, 30, 62, 61, 12, 5, 44,
X 40, 16, 35, 25, 50, 18, 34, 58, 32, 10, 49, 43, 33, 0, 56, 26,
X 9, 59, 24, 2, 1, 57, 48, 42, 54, 29, 36, 19, 6, 5, 44, 62,
X 37, 22, 20, 61, 30, 53, 3, 60, 12, 21, 14, 46, 45, 27, 52, 28,
X 24, 0, 48, 9, 34, 2, 18, 42, 16, 59, 33, 56, 17, 49, 40, 10,
X 58, 43, 8, 51, 50, 41, 32, 26, 38, 13, 20, 3, 53, 52, 28, 46,
X 21, 6, 4, 45, 14, 37, 54, 44, 27, 5, 61, 30, 29, 11, 36, 12,
X 8, 49, 32, 58, 18, 51, 2, 26, 0, 43, 17, 40, 1, 33, 24, 59,
X 42, 56, 57, 35, 34, 25, 16, 10, 22, 60, 4, 54, 37, 36, 12, 30,
X 5, 53, 19, 29, 61, 21, 38, 28, 11, 52, 45, 14, 13, 62, 20, 27,
X 57, 33, 16, 42, 2, 35, 51, 10, 49, 56, 1, 24, 50, 17, 8, 43,
X 26, 40, 41, 48, 18, 9, 0, 59, 6, 44, 19, 38, 21, 20, 27, 14,
X 52, 37, 3, 13, 45, 5, 22, 12, 62, 36, 29, 61, 60, 46, 4, 11,
X 41, 17, 0, 26, 51, 48, 35, 59, 33, 40, 50, 8, 34, 1, 57, 56,
X 10, 24, 25, 32, 2, 58, 49, 43, 53, 28, 3, 22, 5, 4, 11, 61,
X 36, 21, 54, 60, 29, 52, 6, 27, 46, 20, 13, 45, 44, 30, 19, 62,
X 25, 1, 49, 10, 35, 32, 48, 43, 17, 24, 34, 57, 18, 50, 41, 40,
X 59, 8, 9, 16, 51, 42, 33, 56, 37, 12, 54, 6, 52, 19, 62, 45,
X 20, 5, 38, 44, 13, 36, 53, 11, 30, 4, 60, 29, 28, 14, 3, 46,
X 17, 58, 41, 2, 56, 24, 40, 35, 9, 16, 26, 49, 10, 42, 33, 32,
X 51, 0, 1, 8, 43, 34, 25, 48, 29, 4, 46, 61, 44, 11, 54, 37,
X 12, 60, 30, 36, 5, 28, 45, 3, 22, 27, 52, 21, 20, 6, 62, 38
X };
X
X reg int i;
X reg int j;
X reg unsigned long r;
X reg unsb *k;
X
X k = KeyToKS;
X
X for (i = 0; i < 32; i++)
X {
X /* 16-bit tweaks suggested by cip_maz@fb6tcp.physik.uni-paderborn.de */
X /* inlining speedup tweak suggested by tahorsley@csd.harris.com */
X /* (strange addition compensates missing TF_TO_SIXBIT) */
X r = (unsigned long) crypt_block[*(k++)];
X r |= (unsigned long) crypt_block[*(k++)] << 1;
X r |= (unsigned long) crypt_block[*(k++)] << 2;
X r |= (unsigned long) crypt_block[*(k++)] << 3;
X r |= (unsigned long) crypt_block[*(k++)] << 4;
X r |= (unsigned long) crypt_block[*(k++)] << 5;
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 6);
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 7);
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 8);
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 9);
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 10);
X r |= (unsigned long) crypt_block[*(k++)] << (2 + 11);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 12);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 13);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 14);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 15);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 16);
X r |= (unsigned long) crypt_block[*(k++)] << (4 + 17);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 18);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 19);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 20);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 21);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 22);
X r |= (unsigned long) crypt_block[*(k++)] << (6 + 23);
X KS[i] = r;
X }
X}
X
Xvoid
XXForm (saltvalue)
X sbpb24 saltvalue;
X{
X#ifdef BIG_ENDIAN /* Icarus Sparry, Bath - mod AEM */
X#define STEP --
X#define START &sdata.c[7]
X#define Dl sdata.b[1]
X#define Dh sdata.b[0]
X#else /* LITTLE_ENDIAN */
X#define STEP ++
X#define START &sdata.c[0]
X#define Dl sdata.b[0]
X#define Dh sdata.b[1]
X#endif
X union SDATA sdata;
X reg sbpb24 Rl;
X reg sbpb24 Rh;
X reg sbpb24 Ll;
X reg sbpb24 Lh;
X reg sbpb6 *dp;
X int loop;
X int kloop;
X sbpb24 *kp;
X reg sbpb24 k;
X#ifdef FDES_8BYTE
X reg sbpb24 tmpi;
X#endif /* FDES_8BYTE */
X
X Ll = Lh = Rl = Rh = 0;
X
X for (loop = 25; loop--; /* nothing */ )
X {
X kp = KS;
X for (kloop = 8; kloop--; /* nothing */ )
X {
X k = (Rl ^ Rh) & saltvalue;
X#ifndef FDES_8BYTE
X Dl = (k ^ Rl ^ *kp++) << SIZEFIX;
X Dh = (k ^ Rh ^ *kp++) << SIZEFIX;
X#else
X /* hack to make things work better - matthew kaufman */
X /* I haven't tried any of this - I don't have a cray... AEM */
X tmpi = (k ^ Rl ^ *kp++);
X sdata.c[3] = (tmpi >> 24) & 0x00ff;
X sdata.c[2] = (tmpi >> 16) & 0x00ff;
X sdata.c[1] = (tmpi >> 8) & 0x00ff;
X sdata.c[0] = (tmpi) & 0x00ff;
X tmpi = (k ^ Rh ^ *kp++);
X sdata.c[7] = (tmpi >> 24) & 0x00ff;
X sdata.c[6] = (tmpi >> 16) & 0x00ff;
X sdata.c[5] = (tmpi >> 8) & 0x00ff;
X sdata.c[4] = (tmpi) & 0x00ff;
X#endif /* FDES_8BYTE */
X
X dp = START;
X Lh ^= INDIRECT (S0H, *dp);
X Ll ^= INDIRECT (S0L, *dp STEP);
X Lh ^= INDIRECT (S1H, *dp);
X Ll ^= INDIRECT (S1L, *dp STEP);
X Lh ^= INDIRECT (S2H, *dp);
X Ll ^= INDIRECT (S2L, *dp STEP);
X Lh ^= INDIRECT (S3H, *dp);
X Ll ^= INDIRECT (S3L, *dp STEP);
X Lh ^= INDIRECT (S4H, *dp);
X Ll ^= INDIRECT (S4L, *dp STEP);
X Lh ^= INDIRECT (S5H, *dp);
X Ll ^= INDIRECT (S5L, *dp STEP);
X Lh ^= INDIRECT (S6H, *dp);
X Ll ^= INDIRECT (S6L, *dp STEP);
X Lh ^= INDIRECT (S7H, *dp);
X Ll ^= INDIRECT (S7L, *dp STEP);
X
X k = (Ll ^ Lh) & saltvalue;
X#ifndef FDES_8BYTE
X Dl = (k ^ Ll ^ *kp++) << SIZEFIX;
X Dh = (k ^ Lh ^ *kp++) << SIZEFIX;
X#else
X tmpi = (k ^ Ll ^ *kp++);
X sdata.c[3] = (tmpi >> 24) & 0x00ff;
X sdata.c[2] = (tmpi >> 16) & 0x00ff;
X sdata.c[1] = (tmpi >> 8) & 0x00ff;
X sdata.c[0] = (tmpi) & 0x00ff;
X tmpi = (k ^ Lh ^ *kp++);
X sdata.c[7] = (tmpi >> 24) & 0x00ff;
X sdata.c[6] = (tmpi >> 16) & 0x00ff;
X sdata.c[5] = (tmpi >> 8) & 0x00ff;
X sdata.c[4] = (tmpi) & 0x00ff;
X#endif /* FDES_8BYTE */
X
X dp = START;
X Rh ^= INDIRECT (S0H, *dp);
X Rl ^= INDIRECT (S0L, *dp STEP);
X Rh ^= INDIRECT (S1H, *dp);
X Rl ^= INDIRECT (S1L, *dp STEP);
X Rh ^= INDIRECT (S2H, *dp);
X Rl ^= INDIRECT (S2L, *dp STEP);
X Rh ^= INDIRECT (S3H, *dp);
X Rl ^= INDIRECT (S3L, *dp STEP);
X Rh ^= INDIRECT (S4H, *dp);
X Rl ^= INDIRECT (S4L, *dp STEP);
X Rh ^= INDIRECT (S5H, *dp);
X Rl ^= INDIRECT (S5L, *dp STEP);
X Rh ^= INDIRECT (S6H, *dp);
X Rl ^= INDIRECT (S6L, *dp STEP);
X Rh ^= INDIRECT (S7H, *dp);
X Rl ^= INDIRECT (S7L, *dp STEP);
X }
X
X Ll ^= Rl;
X Lh ^= Rh;
X Rl ^= Ll;
X Rh ^= Lh;
X Ll ^= Rl;
X Lh ^= Rh;
X }
X
X /*
X * for reasons that I cannot explain, if I insert the contents of the
X * UnXForm function right HERE, making the tweaks as necessary to avoid
X * using out96[] to pass data, I LOSE 30% of my speed. I don't know why.
X * Hence, I continue to use out96[]...
X */
X {
X reg sbpb24 *qp;
X qp = out96;
X *qp++ = Ll;
X *qp++ = Lh;
X *qp++ = Rl;
X *qp++ = Rh;
X }
X}
X
Xvoid
XUnXForm ()
X{
X reg sbpb24 Rl;
X reg sbpb24 Rh;
X reg sbpb24 Ll;
X reg sbpb24 Lh;
X reg obpb1 *ptr;
X reg long int mask;
X register long int *lip;
X
X Ll = SIXBIT_TO_TF (out96[0]);
X Lh = SIXBIT_TO_TF (out96[1]);
X Rl = SIXBIT_TO_TF (out96[2]);
X Rh = SIXBIT_TO_TF (out96[3]);
X
X#ifdef BUILTIN_CLEAR
X lip = (long int *) crypt_block;
X for (mask = (sizeof (crypt_block) / sizeof (long int)); mask--; /* - */ )
X {
X *(lip++) = 0L;
X }
X#else /* BUILTIN_CLEAR */
X bzero (crypt_block, 66);
X#endif /* BUILTIN_CLEAR */
X
X ptr = crypt_block;
X mask = 0x000400L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x400000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000400L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x400000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000200L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x200000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000200L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x200000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000100L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x100000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000100L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x100000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000080L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x080000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000080L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x080000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000010L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x010000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000010L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x010000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000008L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x008000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000008L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x008000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000004L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x004000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000004L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x004000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000002L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x002000L;
X if (Rl & mask)
X *ptr = 0x01;
X ptr++;
X if (Ll & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x000002L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X mask = 0x002000L;
X if (Rh & mask)
X *ptr = 0x01;
X ptr++;
X if (Lh & mask)
X *ptr = 0x01;
X ptr++;
X}
X
Xchar *
Xfcrypt (pw, salt)
X char *pw;
X char *salt;
X{
X /* Table lookups for salts reduce fcrypt() overhead dramatically */
X static sbpb24 salt0[] =
X {
X 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
X 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
X 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
X 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 5, 6, 7, 8, 9, 10, 11, 12,
X 13, 14, 15, 16, 17,
X
X 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
X 32, 33, 34, 35, 36, 37, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
X 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
X 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
X 12, 13, 14, 15, 16, 17,
X
X 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
X 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
X 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
X 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
X
X 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
X 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
X 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
X 0, 1, 2, 3, 4
X };
X static sbpb24 salt1[] =
X {
X 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
X 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
X 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944,
X 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584,
X 3648, 3712, 3776, 3840, 3904, 3968, 4032, 0, 64, 128, 192, 256,
X 320, 384, 448, 512, 576, 640, 704, 320, 384, 448, 512, 576, 640,
X 704, 768, 832, 896, 960, 1024, 1088,
X
X 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
X 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
X 2368, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560,
X 2624, 2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136, 3200,
X 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840,
X 3904, 3968, 4032, 0, 64, 128, 192, 256, 320, 384, 448, 512, 576,
X 640, 704, 768, 832, 896, 960, 1024, 1088,
X
X 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
X 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
X 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944,
X 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584,
X 3648, 3712, 3776, 3840, 3904, 3968, 4032, 0, 64, 128, 192, 256,
X 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024,
X 1088,
X
X 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
X 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
X 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944,
X 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584,
X 3648, 3712, 3776, 3840, 3904, 3968, 4032, 0, 64, 128, 192, 256
X };
X
X /* final perutation desalting */
X static obpb1 final[] =
X {
X 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66,
X 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
X 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103,
X 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
X 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
X 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
X 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
X 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
X 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
X 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
X 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
X 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
X 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
X 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
X 247, 248, 249, 250, 251, 252, 253, 254, 255,
X /* Truncate overflow bits at 256 */
X 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
X 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
X 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
X 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58
X };
X
X reg int i, j, k;
X reg long int *lip;
X sbpb24 saltvalue;
X
X#ifdef BUILTIN_CLEAR
X lip = (long int *) crypt_block;
X for (i = (sizeof (crypt_block) / sizeof (long int)); i--; /* - */ )
X {
X *(lip++) = 0L;
X }
X#else /* BUILTIN_CLEAR */
X bzero (crypt_block, 66);
X#endif /* BUILTIN_CLEAR */
X
X for (i = 0; (k = *pw) && i < 64; pw++)
X {
X crypt_block[i++] = (k >> 6) & 01;
X crypt_block[i++] = (k >> 5) & 01;
X crypt_block[i++] = (k >> 4) & 01;
X crypt_block[i++] = (k >> 3) & 01;
X crypt_block[i++] = (k >> 2) & 01;
X crypt_block[i++] = (k >> 1) & 01;
X crypt_block[i++] = (k >> 0) & 01;
X i++; /* have to skip one here (parity bit) */
X }
X
X fsetkey ( /* crypt_block */ );
X
X#ifdef BUILTIN_CLEAR
X lip = (long int *) crypt_block;
X for (i = (sizeof (crypt_block) / sizeof (long int)); i--; /* - */ )
X {
X *(lip++) = 0L;
X }
X#else /* BUILTIN_CLEAR */
X bzero (crypt_block, 66);
X#endif /* BUILTIN_CLEAR */
X
X iobuf[0] = salt[0];
X iobuf[1] = salt[1];
X
X saltvalue = salt0[iobuf[0]] | salt1[iobuf[1]];
X saltvalue = TF_TO_SIXBIT (saltvalue);
X
X XForm (saltvalue);
X UnXForm ();
X
X for (i = 0; i < 11; i++)
X {
X k = 0;
X
X for (j = 0; j < 6; j++)
X {
X k = (k << 1) | crypt_block[SIX_TIMES (i) + j];
X }
X iobuf[i + 2] = final[k];
X }
X
X iobuf[i + 2] = 0;
X
X if (iobuf[1] == 0)
X {
X iobuf[1] = iobuf[0];
X }
X return (iobuf);
X}
X/********* INITIALISATION ROUTINES *********/
X
Xfbpb4
XlookupS (tableno, t6bits)
X unsl tableno;
X sbpb6R t6bits;
X{
X static fbpb4R S[8][64] =
X {
X 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
X 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
X 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
X 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
X
X 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
X 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
X 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
X 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
X
X 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
X 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
X 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
X 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
X
X 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
X 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
X 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
X 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
X
X 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
X 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
X 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
X 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
X
X 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
X 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
X 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
X 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
X
X 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
X 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
X 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
X 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
X
X 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
X 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
X 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
X 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
X };
X sbpb6 fixed6bits;
X fbpb4R r;
X fbpb4 fixedr;
X
X fixed6bits = (((t6bits >> 0) & 01) << 5) +
X (((t6bits >> 1) & 01) << 3) +
X (((t6bits >> 2) & 01) << 2) +
X (((t6bits >> 3) & 01) << 1) +
X (((t6bits >> 4) & 01) << 0) +
X (((t6bits >> 5) & 01) << 4);
X
X r = S[tableno][fixed6bits];
X
X fixedr = (((r >> 3) & 01) << 0) +
X (((r >> 2) & 01) << 1) +
X (((r >> 1) & 01) << 2) +
X (((r >> 0) & 01) << 3);
X
X return (fixedr);
X}
X
Xvoid
Xinit (tableno, lowptr, highptr)
X unsl tableno;
X sbpb24 *lowptr, *highptr;
X{
X
X static unsb P[] =
X {
X 15, 6, 19, 20,
X 28, 11, 27, 16,
X 0, 14, 22, 25,
X 4, 17, 30, 9,
X 1, 7, 23, 13,
X 31, 26, 2, 8,
X 18, 12, 29, 5,
X 21, 10, 3, 24,
X };
X
X static unsb E[] =
X {
X 31, 0, 1, 2, 3, 4,
X 3, 4, 5, 6, 7, 8,
X 7, 8, 9, 10, 11, 12,
X 11, 12, 13, 14, 15, 16,
X 15, 16, 17, 18, 19, 20,
X 19, 20, 21, 22, 23, 24,
X 23, 24, 25, 26, 27, 28,
X 27, 28, 29, 30, 31, 0,
X };
X
X static obpb1 tmp32[32];
X static obpb1 tmpP32[32];
X static obpb1 tmpE[48];
X
X int j, k, i;
X int tablenoX4;
X reg sbpb24 spare24;
X
X tablenoX4 = tableno * 4;
X
X for (j = 0; j < 64; j++)
X {
X k = lookupS (tableno, j);
X
X for (i = 0; i < 32; i++)
X {
X tmp32[i] = 0;
X }
X for (i = 0; i < 4; i++)
X {
X tmp32[tablenoX4 + i] = (k >> i) & 01;
X }
X for (i = 0; i < 32; i++)
X {
X tmpP32[i] = tmp32[P[i]];
X }
X for (i = 0; i < 48; i++)
X {
X tmpE[i] = tmpP32[E[i]];
X }
X
X lowptr[j] = 0;
X highptr[j] = 0;
X
X for (i = 0; i < 24; i++)
X {
X lowptr[j] |= (unsigned long) tmpE[i] << i;
X }
X for (k = 0, i = 24; i < 48; i++, k++)
X {
X highptr[j] |= (unsigned long) tmpE[i] << k;
X }
X
X spare24 = lowptr[j]; /* to allow for macro expansion */
X lowptr[j] = TF_TO_SIXBIT (spare24);
X spare24 = highptr[j]; /* to allow for macro expansion */
X highptr[j] = TF_TO_SIXBIT (spare24);
X }
X}
Xinit_des ()
X{
X init (0L, S0L, S0H);
X init (1L, S1L, S1H);
X init (2L, S2L, S2H);
X init (3L, S3L, S3H);
X init (4L, S4L, S4H);
X init (5L, S5L, S5H);
X init (6L, S6L, S6H);
X init (7L, S7L, S7H);
X}
END_OF_FILE
if test 22754 -ne `wc -c <'Sources/crack-fcrypt.c'`; then
echo shar: \"'Sources/crack-fcrypt.c'\" unpacked with wrong size!
fi
# end of 'Sources/crack-fcrypt.c'
fi
echo shar: End of archive 3 \(of 5\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 5 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.