Dual personality crypt(3). This crypt will choose its encryption algorithm
(DES or MD5) based on the type of salt used. Salt beginning with "$1$" indicates MD5.
This commit is contained in:
parent
7a7d7c9ee6
commit
96e718fe29
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=12884
@ -1,29 +1,23 @@
|
||||
#
|
||||
# $Id: Makefile,v 1.6 1994/08/26 19:03:23 wollman Exp $
|
||||
# $Id$
|
||||
#
|
||||
|
||||
LCRYPTBASE= libcrypt
|
||||
LCRYPTSO= $(LCRYPTBASE).so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
|
||||
|
||||
|
||||
LDCRYPTBASE= libdescrypt
|
||||
LDCRYPTSO= $(LDCRYPTBASE).so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
|
||||
|
||||
.PATH: ${.CURDIR}/../../../lib/libmd
|
||||
|
||||
LIB= descrypt
|
||||
SRCS= crypt.c
|
||||
SRCS= crypt.c crypt-md5.c md5c.c
|
||||
CFLAGS+= -I${.CURDIR}/../../../lib/libmd -Wall
|
||||
PRECIOUSLIB= yes
|
||||
|
||||
#MAN3= crypt.3
|
||||
#MLINKS= crypt.3 encrypt.3 crypt.3 setkey.3
|
||||
#MLINKS+=crypt.3 des_cipher.3 crypt.3 des_setkey.3
|
||||
|
||||
|
||||
|
||||
|
||||
test:
|
||||
cd test ; make test ; make clean
|
||||
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
||||
# We only install the links if they do not already exist.
|
||||
@ -48,5 +42,3 @@ afterinstall:
|
||||
ln -s $(LDCRYPTBASE)_p.a libcrypt_p.a; \
|
||||
fi
|
||||
.endif
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: crypt.c,v 1.5 1994/09/19 19:26:39 csgr Exp $
|
||||
* $Id$
|
||||
*
|
||||
* This is an original implementation of the DES and the crypt(3) interfaces
|
||||
* by David Burren <davidb@werj.com.au>.
|
||||
@ -58,10 +58,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
char *crypt_md5(const char *pw, const char *salt);
|
||||
|
||||
/* We can't always assume gcc */
|
||||
#ifdef __GNUC__
|
||||
@ -366,7 +365,7 @@ static int
|
||||
des_setkey(const char *key)
|
||||
{
|
||||
u_long k0, k1, rawkey0, rawkey1;
|
||||
int shifts, i, b, round;
|
||||
int shifts, round;
|
||||
|
||||
if (!des_initialised)
|
||||
des_init();
|
||||
@ -413,7 +412,6 @@ des_setkey(const char *key)
|
||||
shifts = 0;
|
||||
for (round = 0; round < 16; round++) {
|
||||
u_long t0, t1;
|
||||
int bit;
|
||||
|
||||
shifts += key_shifts[round];
|
||||
|
||||
@ -449,9 +447,9 @@ do_des( u_long l_in, u_long r_in, u_long *l_out, u_long *r_out, int count)
|
||||
/*
|
||||
* l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
|
||||
*/
|
||||
u_long mask, rawl, rawr, l, r, *kl, *kr, *kl1, *kr1;
|
||||
u_long l, r, *kl, *kr, *kl1, *kr1;
|
||||
u_long f, r48l, r48r;
|
||||
int i, j, b, round;
|
||||
int round;
|
||||
|
||||
if (count == 0) {
|
||||
return(1);
|
||||
@ -580,7 +578,6 @@ des_cipher(const char *in, char *out, long salt, int count)
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
crypt(char *key, char *setting)
|
||||
{
|
||||
@ -589,6 +586,9 @@ crypt(char *key, char *setting)
|
||||
u_char *p, *q;
|
||||
static u_char output[21];
|
||||
|
||||
if (!strncmp(setting, "$1$", 3))
|
||||
return crypt_md5(key, setting);
|
||||
|
||||
if (!des_initialised)
|
||||
des_init();
|
||||
|
||||
@ -599,7 +599,7 @@ crypt(char *key, char *setting)
|
||||
*/
|
||||
q = (u_char *) keybuf;
|
||||
while (q - (u_char *) keybuf - 8) {
|
||||
if (*q++ = *key << 1)
|
||||
if ((*q++ = *key << 1))
|
||||
key++;
|
||||
}
|
||||
if (des_setkey((u_char *) keybuf))
|
||||
|
157
secure/lib/libcrypt/crypt-md5.c
Normal file
157
secure/lib/libcrypt/crypt-md5.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* This has had its entry point changed to crypt_md5 for use in
|
||||
* a dual-personality (DES & MD5) environment) -- MarkM - Nov 1995
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char rcsid[] = "$Header: /home/ncvs/src/lib/libcrypt/crypt.c,v 1.3 1995/05/30 05:42:22 rgrimes Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <md5.h>
|
||||
|
||||
static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
|
||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
static void
|
||||
to64(s, v, n)
|
||||
char *s;
|
||||
unsigned long v;
|
||||
int n;
|
||||
{
|
||||
while (--n >= 0) {
|
||||
*s++ = itoa64[v&0x3f];
|
||||
v >>= 6;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* UNIX password
|
||||
*
|
||||
* Use MD5 for what it is best at...
|
||||
*/
|
||||
|
||||
char *
|
||||
crypt_md5(pw, salt)
|
||||
register const char *pw;
|
||||
register const char *salt;
|
||||
{
|
||||
static char *magic = "$1$"; /*
|
||||
* This string is magic for
|
||||
* this algorithm. Having
|
||||
* it this way, we can get
|
||||
* get better later on
|
||||
*/
|
||||
static char passwd[120], *p;
|
||||
static const char *sp,*ep;
|
||||
unsigned char final[16];
|
||||
int sl,pl,i,j;
|
||||
MD5_CTX ctx,ctx1;
|
||||
unsigned long l;
|
||||
|
||||
/* Refine the Salt first */
|
||||
sp = salt;
|
||||
|
||||
/* If it starts with the magic string, then skip that */
|
||||
if(!strncmp(sp,magic,strlen(magic)))
|
||||
sp += strlen(magic);
|
||||
|
||||
/* It stops at the first '$', max 8 chars */
|
||||
for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
|
||||
continue;
|
||||
|
||||
/* get the length of the true salt */
|
||||
sl = ep - sp;
|
||||
|
||||
MD5Init(&ctx);
|
||||
|
||||
/* The password first, since that is what is most unknown */
|
||||
MD5Update(&ctx,pw,strlen(pw));
|
||||
|
||||
/* Then our magic string */
|
||||
MD5Update(&ctx,magic,strlen(magic));
|
||||
|
||||
/* Then the raw salt */
|
||||
MD5Update(&ctx,sp,sl);
|
||||
|
||||
/* Then just as many characters of the MD5(pw,salt,pw) */
|
||||
MD5Init(&ctx1);
|
||||
MD5Update(&ctx1,pw,strlen(pw));
|
||||
MD5Update(&ctx1,sp,sl);
|
||||
MD5Update(&ctx1,pw,strlen(pw));
|
||||
MD5Final(final,&ctx1);
|
||||
for(pl = strlen(pw); pl > 0; pl -= 16)
|
||||
MD5Update(&ctx,final,pl>16 ? 16 : pl);
|
||||
|
||||
/* Don't leave anything around in vm they could use. */
|
||||
memset(final,0,sizeof final);
|
||||
|
||||
/* Then something really weird... */
|
||||
for (j=0,i = strlen(pw); i ; i >>= 1)
|
||||
if(i&1)
|
||||
MD5Update(&ctx, final+j, 1);
|
||||
else
|
||||
MD5Update(&ctx, pw+j, 1);
|
||||
|
||||
/* Now make the output string */
|
||||
strcpy(passwd,magic);
|
||||
strncat(passwd,sp,sl);
|
||||
strcat(passwd,"$");
|
||||
|
||||
MD5Final(final,&ctx);
|
||||
|
||||
/*
|
||||
* and now, just to make sure things don't run too fast
|
||||
* On a 60 Mhz Pentium this takes 34 msec, so you would
|
||||
* need 30 seconds to build a 1000 entry dictionary...
|
||||
*/
|
||||
for(i=0;i<1000;i++) {
|
||||
MD5Init(&ctx1);
|
||||
if(i & 1)
|
||||
MD5Update(&ctx1,pw,strlen(pw));
|
||||
else
|
||||
MD5Update(&ctx1,final,16);
|
||||
|
||||
if(i % 3)
|
||||
MD5Update(&ctx1,sp,sl);
|
||||
|
||||
if(i % 7)
|
||||
MD5Update(&ctx1,pw,strlen(pw));
|
||||
|
||||
if(i & 1)
|
||||
MD5Update(&ctx1,final,16);
|
||||
else
|
||||
MD5Update(&ctx1,pw,strlen(pw));
|
||||
MD5Final(final,&ctx1);
|
||||
}
|
||||
|
||||
p = passwd + strlen(passwd);
|
||||
|
||||
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
|
||||
l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
|
||||
l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
|
||||
l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
|
||||
l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
|
||||
l = final[11] ; to64(p,l,2); p += 2;
|
||||
*p = '\0';
|
||||
|
||||
/* Don't leave anything around in vm they could use. */
|
||||
memset(final,0,sizeof final);
|
||||
|
||||
return passwd;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $Id: crypt.3,v 1.1.1.1 1994/04/04 14:57:18 g89r4222 Exp $
|
||||
.\" $Id$
|
||||
.\"
|
||||
.\" Manual page, using -mandoc macros
|
||||
.\"
|
||||
@ -100,6 +100,14 @@ Thus only 12 bits of
|
||||
are used.
|
||||
.Fa count
|
||||
is set to 25.
|
||||
.Ss "FreeBSD" or "Exportable" crypt:
|
||||
.Pp
|
||||
If the salt begins with ``$1$'' then the freely exportable
|
||||
.Tn MD5
|
||||
algorithm is used to calculate a hash value, from which the password string
|
||||
is generated. The
|
||||
.Tn MD5
|
||||
derived routine is designed to be time-consuming like the DES based version.
|
||||
.Ss Algorithm:
|
||||
.Pp
|
||||
The
|
||||
|
@ -32,7 +32,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: crypt.c,v 1.5 1994/09/19 19:26:39 csgr Exp $
|
||||
* $Id$
|
||||
*
|
||||
* This is an original implementation of the DES and the crypt(3) interfaces
|
||||
* by David Burren <davidb@werj.com.au>.
|
||||
@ -58,10 +58,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
char *crypt_md5(const char *pw, const char *salt);
|
||||
|
||||
/* We can't always assume gcc */
|
||||
#ifdef __GNUC__
|
||||
@ -366,7 +365,7 @@ static int
|
||||
des_setkey(const char *key)
|
||||
{
|
||||
u_long k0, k1, rawkey0, rawkey1;
|
||||
int shifts, i, b, round;
|
||||
int shifts, round;
|
||||
|
||||
if (!des_initialised)
|
||||
des_init();
|
||||
@ -413,7 +412,6 @@ des_setkey(const char *key)
|
||||
shifts = 0;
|
||||
for (round = 0; round < 16; round++) {
|
||||
u_long t0, t1;
|
||||
int bit;
|
||||
|
||||
shifts += key_shifts[round];
|
||||
|
||||
@ -449,9 +447,9 @@ do_des( u_long l_in, u_long r_in, u_long *l_out, u_long *r_out, int count)
|
||||
/*
|
||||
* l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
|
||||
*/
|
||||
u_long mask, rawl, rawr, l, r, *kl, *kr, *kl1, *kr1;
|
||||
u_long l, r, *kl, *kr, *kl1, *kr1;
|
||||
u_long f, r48l, r48r;
|
||||
int i, j, b, round;
|
||||
int round;
|
||||
|
||||
if (count == 0) {
|
||||
return(1);
|
||||
@ -580,7 +578,6 @@ des_cipher(const char *in, char *out, long salt, int count)
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
crypt(char *key, char *setting)
|
||||
{
|
||||
@ -589,6 +586,9 @@ crypt(char *key, char *setting)
|
||||
u_char *p, *q;
|
||||
static u_char output[21];
|
||||
|
||||
if (!strncmp(setting, "$1$", 3))
|
||||
return crypt_md5(key, setting);
|
||||
|
||||
if (!des_initialised)
|
||||
des_init();
|
||||
|
||||
@ -599,7 +599,7 @@ crypt(char *key, char *setting)
|
||||
*/
|
||||
q = (u_char *) keybuf;
|
||||
while (q - (u_char *) keybuf - 8) {
|
||||
if (*q++ = *key << 1)
|
||||
if ((*q++ = *key << 1))
|
||||
key++;
|
||||
}
|
||||
if (des_setkey((u_char *) keybuf))
|
||||
|
Loading…
Reference in New Issue
Block a user