[comp.os.minix] Crypt

meulenbr@cstw01.prl.philips.nl (Frans Meulenbroeks) (09/28/89)

Hi!

When looking at crypt(3) I noticed a few problems:
1) crypt has been changed during the traverse from PC 1.2 to PC 1.3
   Since I don't think both crypts are equivalent this implies that
   if you upgrade and rebuild init the original passwd file will
   not work any more.
2) The new crypt contains a bug
   Some code fragments:
	...
        register char bits[67];
	...
        for (i=0; i < 12; i++) {
                buf[i+2] = 0;
                for (j=0; j < 6; j++)
                        buf[i+2] |= (bits[i*6+j] ? (1 << j) : 0);
	...
	
   Since i can grow to 11 and j to 5 the expression i*6+j can be as
   large as 71 exceeding the maximum allowed value of 66

Since the code of crypt is quite cryptic, and because the lack of
comments in the code, I've no idea how to fix this. Any suggestion
is welcome.

Regards,
Frans Meulenbroeks        (meulenbr@cst.prl.philips.nl)
	Centre for Software Technology
	( or try: ...!mcvax!phigate!prle!cst!meulenbr)

root@cca.ucsf.edu (Systems Staff) (06/29/90)

In article <22918@nigel.udel.EDU>, archer%segin4.segin.fr@prime.com (Vincent Archer) writes:

> There's a solution that will satisfy everyone: use a scrambler rather than a
> crypter. A scrambler's output is not reversible (like passwords in /etc/passwd
> should be), so scramblers algorithm are not considered as "sensible material".
> Unfortunately, I do not have a scrambler algorithm at hand, but here's an idea:

[description of algorithm deleted]

>   I sincerely doubt that this function would be reversible. If anybody can
>   think of an algorithm that (even with the salt value) gives back the original
>   password, well, maths can do wonders :-)

Remember, for password applications the function need not be reversible.
All you need to do is find _any_ string which will yield the desired
result; it need not be the original.

> For those who don't like maths (especially boolean arithmetics), I'll try to
> write a crypt() that use this algorithm, if nobody has anything better to
> propose.

Two powerful algorithms have recently had full source code posted:

    MD4 by Ron Rivest (R of RSA)

and

    Snefru by Ralph Merkle

I doubt that it is worth your while trying to improve on these. They
produce longer scrambles than most Unix systems use in their passwords
so there are some questions involved in their application.

I suggest that you include a confidential addendum specific to each
machine in the message being scrambled to avoid the defect in the
Unix password system that allows transferring password data to other
machines for cracking.

 Thos Sumner       Internet: thos@cca.ucsf.edu
 (The I.G.)        UUCP: ...ucbvax!ucsfcgl!cca.ucsf!thos
                   BITNET:  thos@ucsfcca

 U.S. Mail:  Thos Sumner, Computer Center, Rm U-76, UCSF
             San Francisco, CA 94143-0704 USA

I hear nothing in life is certain but death and taxes -- and they're
working on death.

#include <disclaimer.std>

drd@siia.mv.com (David Dick) (06/30/90)

In <22918@nigel.udel.EDU> archer%segin4.segin.fr@prime.com (Vincent Archer) writes:

>There's a solution that will satisfy everyone: use a scrambler rather than a
>crypter. A scrambler's output is not reversible (like passwords in /etc/passwd
>should be), so scramblers algorithm are not considered as "sensible material".
>Unfortunately, I do not have a scrambler algorithm at hand, but here's an idea:

>- Create a 64*64 matrix of bits, using somehow the password and the salt. An
>  example of a good matrix output would be the set of bits generated by the
>  crc algorithm applid on a cyclic pattern taken from the password, skipping
>  the first "salt" bits.
>- Multiply the vector of bits from the password by this matrix. You get a
>  new vector of bits that is the "scrambled" password, which you put in your
>  /etc/passwd (or use in /bin/login, /usr/bin/su, or any program that strikes
>  your fancy).

>  I sincerely doubt that this function would be reversible. If anybody can
>  think of an algorithm that (even with the salt value) gives back the original
>  password, well, maths can do wonders :-)

I don't think there is any particular reason to believe
this is a non-reversible function.  I also don't understand
the distinction you are drawing between "crypters" and "scramblers".

David Dick
Software Innovations, Inc. [the Software Moving Company(sm)]

kjh@pollux.usc.edu (Kenneth J. Hendrickson) (07/01/90)

I "borrowed" the source for crypt() from a BSD system near me, and
installed it.  Everything went just fine, except ...

	After one failed login attempt (due to bad username or passwd),
	Nobody can ever log in again!  Not even with a good passwd!

Can anybody supply hints as to where I should start looking to find this
problem?

Ken Hendrickson N8DGN/6      kjh@usc.edu      ...!uunet!usc!pollux!kjh

kjh@pollux.usc.edu (Kenneth J. Hendrickson) (07/01/90)

In article <25628@usc.edu> kjh@pollux.usc.edu (Kenneth J. Hendrickson) writes:
>	After one failed login attempt (due to bad username or passwd),
>	Nobody can ever log in again!  Not even with a good passwd!

Investigation has revealed the following:

(1) Successive calls to crypt() in minix return different values,
    even with the same inputs to crypt().

(2) Successive calls to crypt() on several different BSD boxes return
    exactly the same values every time, with the same inputs to crypt().

(3) Minix seems to call crypt() in login.c in exactly the same way that
    the BSD boxes call crypt() in login.c.

(4) Crypt() itself does not change any of the variables declared static
    and defined outside of any function.  There is no indication that
    the crypt() I have is destroying itself at runtime.

HELP!  Something really obscure is happening here, and I would still
appreciate any pointers.  (I didn't get any with my last request.)

Ken Hendrickson N8DGN/6      kjh@usc.edu      ...!uunet!usc!pollux!kjh

kjh@pollux.usc.edu (Kenneth J. Hendrickson) (07/02/90)

>In article <25628@usc.edu> kjh@pollux.usc.edu (Kenneth J. Hendrickson) writes:
>	After one failed login attempt (due to bad username or passwd),
>	Nobody can ever log in again!  Not even with a good passwd!
>
>Investigation has revealed the following:
>
>(1) Successive calls to crypt() in minix return different values,
>    even with the same inputs to crypt().

Here is the problem:

/* Modified for MINIX by Kenneth J. Hendrickson kjh@usc.edu, 2 July 1990
 *
 * The code in encrypt() required that R[] immediately follow L[].
 *
 * In Minix, the C compiler places unitialized static variables that are
 * declared outside a function in the bss segment, but in the _opposite_
 * order from which they are declared.
 */

The wise guy who wrote the code for crypt() did something that was
system (actually compiler) dependant.  Now maybe the wise guy is wiser
than I, and K&R specify that all static variables go into the bss
segment in the order in which they are declared, but I'm not aware of
this.  If I was defining the C language, I certainly wouldn't have done
this.  If K&R did specify this, then of course the Minix C compiler is
broken.

I am willing to email my working crypt() for Minix, which is
functionally equivalent to the crypt() on the BSD boxes, to anybody on
a US site.  The US has a law about taking encryption technology out of
the country, and there are two things I want to avoid: (1) I don't want
the media to find out about me mailing it out of the US, and making me
into a Benedict Arnold, and (2) I don't want the Feds to show up at my
door with burp guns.  Please note that I think the law is silly, since
the DES algorithm is well known.  You can even find it in Pascal :-( in
Dr. Tanenbaum's book on Computer Networks.

During my testing and debugging, I found a small bug in login.c (which
will never cause any problems, but is a bug nonetheless).  Here is my
patch to login.c:

begin 600 login.c.cdif
M*BHJ("]U<W(O<W)C+VUI;FEX+V-O;6UA;F1S+VQO9VEN+F,)5&AU($UA>2 S
M,2 P-#HT.#HU," Q.3DP"BTM+2 O=7-R+W-R8R]L;V-A;"]C;VUM86YD<R]L
M;V=I;BYC"5-U;B!*=6P@(#$@,3DZ,38Z-#$@,3DY, HJ*BHJ*BHJ*BHJ*BHJ
M*BH**BHJ(#,X+#0S("HJ*BH*+2TM(#,X+#0V("TM+2T*(" @*@H@(" J($%N
M9'D@5&%N96YB875M($%P<FEL(#$Y.3 *(" @*B M(&EF("]B:6XO<V@@8V%N
M;F]T(&)E(&QO8V%T960L('1R>2 O=7-R+V)I;B]S: HK(" J"BL@("H@2V5N
M;F5T:"!*+B!(96YD<FEC:W-O;B H:VIH0'5S8RYE9'4I($IU;'D@,3DY, HK
M(" J("T@<F5M;W9E9"!U<V5L97-S(&-A;&P@=&\@8W)Y<'0@=VET:"!S86QT
M/2)A86%A(@H@(" J+PH@( H@("-I;F-L=61E(#QS>7,O='EP97,N:#X**BHJ
M*BHJ*BHJ*BHJ*BHJ"BHJ*B R-C,L,C8Y("HJ*BH*(" )"6%R9W,N<V=?9FQA
M9W,@?#T@14-(3SL*(" )"6EO8W1L*# L(%1)3T-31510+" F87)G<RD["B @
M"B$@"0EI9B H8F%D("8F(&-R>7!T*'!A<W-W;W)D+" B86%A82(I('Q\"B @
M"0D@(" @<W1R8VUP*'!W9"T^<'=?<&%S<W=D+"!C<GEP="AP87-S=V]R9"P@
M<'=D+3YP=U]P87-S=V0I*2D@>PH@("-I9F1E9B!"041,3T<*(" )"0EA9&1L
M;V<H;F%M92P@<&%S<W=O<F0L('1T>6YA;64I.PHM+2T@,C8V+#(W,B M+2TM
M"B @"0EA<F=S+G-G7V9L86=S('P]($5#2$\["B @"0EI;V-T;"@P+"!424]#
M4T544"P@)F%R9W,I.PH@( HA( D):68@*&)A9"!\? H@( D)(" @('-T<F-M
M<"AP=V0M/G!W7W!A<W-W9"P@8W)Y<'0H<&%S<W=O<F0L('!W9"T^<'=?<&%S
M<W=D*2DI('L*(" C:69D968@0D%$3$]'"B @"0D)861D;&]G*&YA;64L('!A
2<W-W;W)D+"!T='EN86UE*3L*
 
end

Ken Hendrickson N8DGN/6      kjh@usc.edu      ...!uunet!usc!pollux!kjh

archer%segin4.segin.fr@prime.com (Vincent Archer) (07/04/90)

In <22918@nigel.udel.EDU> archer%segin4.segin.fr@prime.com (Vincent Archer) writes:

David Dick <drd@siia.mv.com> writes:
> [stuff from my crypt(3) algorithm deleted]
>
> >  I sincerely doubt that this function would be reversible. If anybody can
> >  think of an algorithm that (even with the salt value) gives back the
> >  original password, well, maths can do wonders :-)
>
> I don't think there is any particular reason to believe
> this is a non-reversible function.  I also don't understand
> the distinction you are drawing between "crypters" and "scramblers".

There's a simple fact that makes it a non-reversible function: more than 5000
bits of the password are used to produce a 64-bits output. So, ouf course,
there's no reversibility possible, as many passwords (most of them outside of
the usual ascii range) can (and will) produce the same encrypted result. This
is a default in the password encoding scheme (existence of unknown but valid
passwords), but it's better than the previous situation.

As for crypters & Scramblers, well, a crypter can be reversed, and (given the
key), you can find the original data from the destination one. A scrambler
cannot be reversed; there's no way from final to initial datas. My crypt(3)
is a scrambler (two inputs can give the same output), the original crypt(3)
from Minix is a crypter (and a bad one, it seems).


    Vincent


Vincent Archer                   | Email:archer%segin4.segin.fr@prime.com
"People that are good at finding excuses are never good at anything else"

csg020@cck.cov.ac.uk (***CURTIS***) (06/17/91)

Sorry if this question is one of the easiest any of you have had to answer but
I'm just getting to grips with Minix.

I now have a new version of crypt.c that's from Andy Tannenbaums Op systems
(or so it says in the comments). Now my problem is I want to install it
into the library. How do I do it? I have found the old version is embedded in
libc.a (I think) but how do I recompile it?

Cheers for any help.



-- 
_______________________________________________________________________________
| Flesh : ***CURTIS*** E-mail : csg020%uk.ac.cov.cck@uk.ac.earn-relay         |
| Voice : (0203) 599500 Quote : What a great day, watch some bastard spoil it!|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

al@escom.com (Al Donaldson) (06/18/91)

csg020@cck.cov.ac.uk (***CURTIS***) writes:
> I now have a new version of crypt.c ... I want to install it
> into the library. ... but how do I recompile it?

It should be a fairly standard update of a library function.
Without seeing the code, I would:

 - make a copy of the old src/lib/other/crypt.c, just in case
 - replace the old src/lib/other/crypt.c with the new one
 - compile the new crypt.c--see the Makefile for flags, etc.
 - install the new crypt.s in /usr/lib/libc.a--see the man page
   example for "ar r" for details

But that is the easy part.  Knuckle-biting time comes when you
recompile passwd.c, login.c, and su.c with the new crypt.s
and then start playing with the password file.

I recommend that you *temporarily* remove the encrypted password
for root from your /etc/passwd file.  This way, if things go wrong,
you can get back in and fix them.  (I did this on a system that
didn't allow login if the user's password field was empty.  Talk
about a pucker factor... :-)

Now recompile the passwd, login, and su programs using the new
library and install them in the appropriate bin directories,
with the appropriate modes, setuid bits, and ownership.  You
might want to rename the old versions (e.g., "mv login login.OLD)
beforehand, and then ls -l both the old and new versions to be
sure that you have everything the same.  Check them again.

Next change the password for a general user (e.g., ast) using
the new passwd program.  Inspect the /etc/passwd file.  If it
looks OK (exactly 13 bytes in the password field for your user
and none of the other users have been hammered), then logout
and login again as that user.  If you get in this time time,
then the chances are everthing works OK and you can go ahead
and change all the passwords in the password file, including
restoring the root password.

If not, well you get some valuable lessons in debugging. :-)

Al

PS - You did save the old src/lib/other/crypt.c, /usr/lib/libc.a,
and /etc/passwd files and the login, su, and passwd binaries,
didn't you?