mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-27 13:32:45 +00:00
MFH (r261913): switch default to sha512
MFH (r264964): rewrite so DES still works when not the default MFH (r262945): clean up man page
This commit is contained in:
parent
3e35f5c89f
commit
895309a5b5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/stable/10/; revision=265879
@ -29,7 +29,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 9, 2011
|
||||
.Dd March 9, 2014
|
||||
.Dt CRYPT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -63,11 +63,16 @@ Currently these include the
|
||||
.Tn MD5
|
||||
hash,
|
||||
.Tn NT-Hash
|
||||
(compatible with Microsoft's NT scheme)
|
||||
.Pq compatible with Microsoft's NT scheme
|
||||
and
|
||||
.Tn Blowfish .
|
||||
The algorithm used will depend upon the format of the Salt (following
|
||||
the Modular Crypt Format (MCF)), if
|
||||
The algorithm used will depend upon the format of the Salt
|
||||
.Po
|
||||
following
|
||||
the Modular Crypt Format
|
||||
.Pq MCF
|
||||
.Pc ,
|
||||
if
|
||||
.Tn DES
|
||||
and/or
|
||||
.Tn Blowfish
|
||||
@ -77,8 +82,10 @@ has been called to change the default.
|
||||
.Pp
|
||||
The first argument to
|
||||
.Nm
|
||||
is the data to hash (usually a password), in a
|
||||
.Dv null Ns -terminated
|
||||
is the data to hash
|
||||
.Pq usually a password ,
|
||||
in a
|
||||
.Dv NUL Ns -terminated
|
||||
string.
|
||||
The second is the salt, in one of three forms:
|
||||
.Pp
|
||||
@ -96,22 +103,19 @@ If it begins with the string
|
||||
then the Modular Crypt Format is used, as outlined below.
|
||||
.It Traditional
|
||||
If neither of the above is true, it assumes the Traditional Format,
|
||||
using the entire string as the salt (or the first portion).
|
||||
using the entire string as the salt
|
||||
.Pq or the first portion .
|
||||
.El
|
||||
.Pp
|
||||
All routines are designed to be time-consuming.
|
||||
A brief test on a
|
||||
.Tn Pentium
|
||||
166/MMX shows the
|
||||
.Tn DES
|
||||
crypt to do approximately 2640 crypts
|
||||
a CPU second and MD5 to do about 62 crypts a CPU second.
|
||||
.Ss DES Extended Format:
|
||||
The
|
||||
.Ar key
|
||||
is divided into groups of 8 characters (the last group is null-padded)
|
||||
and the low-order 7 bits of each character (56 bits per group) are
|
||||
used to form the
|
||||
is divided into groups of 8 characters
|
||||
.Pq the last group is NUL-padded
|
||||
and the low-order 7 bits of each character
|
||||
.Pq 56 bits per group
|
||||
are used to form the
|
||||
.Tn DES
|
||||
key as follows:
|
||||
the first group of 56 bits becomes the initial
|
||||
@ -127,7 +131,8 @@ The salt is a 9-character array consisting of an underscore followed
|
||||
by 4 bytes of iteration count and 4 bytes of salt.
|
||||
These are encoded as printable characters, 6 bits per character,
|
||||
least significant character first.
|
||||
The values 0 to 63 are encoded as ``./0-9A-Za-z''.
|
||||
The values 0 to 63 are encoded as
|
||||
.Dq ./0-9A-Za-z .
|
||||
This allows 24 bits for both
|
||||
.Fa count
|
||||
and
|
||||
@ -138,7 +143,8 @@ The
|
||||
introduces disorder in the
|
||||
.Tn DES
|
||||
algorithm in one of 16777216 or 4096 possible ways
|
||||
(i.e., with 24 or 12 bits: if bit
|
||||
.Po
|
||||
i.e., with 24 or 12 bits: if bit
|
||||
.Em i
|
||||
of the
|
||||
.Ar salt
|
||||
@ -148,7 +154,8 @@ and
|
||||
.Em i+24
|
||||
are swapped in the
|
||||
.Tn DES
|
||||
E-box output).
|
||||
E-box output
|
||||
.Pc .
|
||||
.Pp
|
||||
The
|
||||
.Tn DES
|
||||
@ -157,11 +164,13 @@ key is used to encrypt a 64-bit constant using
|
||||
iterations of
|
||||
.Tn DES .
|
||||
The value returned is a
|
||||
.Dv null Ns -terminated
|
||||
string, 20 or 13 bytes (plus null) in length, consisting of the
|
||||
.Dv NUL Ns -terminated
|
||||
string, 20 or 13 bytes
|
||||
.Pq plus NUL
|
||||
in length, consisting of the
|
||||
.Ar salt
|
||||
followed by the encoded 64-bit encryption.
|
||||
.Ss "Modular" crypt:
|
||||
.Ss Modular crypt:
|
||||
If the salt begins with the string
|
||||
.Fa $digit$
|
||||
then the Modular Crypt Format is used.
|
||||
@ -170,11 +179,10 @@ The
|
||||
represents which algorithm is used in encryption.
|
||||
Following the token is
|
||||
the actual salt to use in the encryption.
|
||||
The length of the salt is limited
|
||||
to 8 characters--because the length of the returned output is also limited
|
||||
(_PASSWORD_LEN).
|
||||
The salt must be terminated with the end of the string
|
||||
(NULL) or a dollar sign.
|
||||
The maximum length of the salt used depends upon the module.
|
||||
The salt must be terminated with the end of the string character
|
||||
.Pq NUL
|
||||
or a dollar sign.
|
||||
Any characters after the dollar sign are ignored.
|
||||
.Pp
|
||||
Currently supported algorithms are:
|
||||
@ -199,7 +207,7 @@ An example salt would be:
|
||||
.Bl -tag -width 6n -offset indent
|
||||
.It Cm "$4$thesalt$rest"
|
||||
.El
|
||||
.Ss "Traditional" crypt:
|
||||
.Ss Traditional crypt:
|
||||
The algorithm used will depend upon whether
|
||||
.Fn crypt_set_format
|
||||
has been called and whether a global default format has been specified.
|
||||
@ -216,7 +224,7 @@ if it is available, or MD5 if not.
|
||||
.Pp
|
||||
How the salt is used will depend upon the algorithm for the hash.
|
||||
For
|
||||
best results, specify at least two characters of salt.
|
||||
best results, specify at least eight characters of salt.
|
||||
.Pp
|
||||
The
|
||||
.Fn crypt_get_format
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 1999
|
||||
* Mark Murray. All rights reserved.
|
||||
/*-
|
||||
* Copyright (c) 1999 Mark Murray
|
||||
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -28,114 +29,88 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libutil.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "crypt.h"
|
||||
|
||||
static const struct {
|
||||
/*
|
||||
* List of supported crypt(3) formats. The first element in the list will
|
||||
* be the default.
|
||||
*/
|
||||
static const struct crypt_format {
|
||||
const char *const name;
|
||||
char *(*const func)(const char *, const char *);
|
||||
const char *const magic;
|
||||
} crypt_types[] = {
|
||||
#ifdef HAS_DES
|
||||
{
|
||||
"des",
|
||||
crypt_des,
|
||||
NULL
|
||||
},
|
||||
#endif
|
||||
{
|
||||
"md5",
|
||||
crypt_md5,
|
||||
"$1$"
|
||||
},
|
||||
} crypt_formats[] = {
|
||||
/* default format */
|
||||
{ "sha512", crypt_sha512, "$6$" },
|
||||
|
||||
/* other supported formats */
|
||||
{ "md5", crypt_md5, "$1$" },
|
||||
#ifdef HAS_BLOWFISH
|
||||
{
|
||||
"blf",
|
||||
crypt_blowfish,
|
||||
"$2"
|
||||
},
|
||||
{ "blf", crypt_blowfish, "$2" },
|
||||
#endif
|
||||
{
|
||||
"nth",
|
||||
crypt_nthash,
|
||||
"$3$"
|
||||
},
|
||||
{
|
||||
"sha256",
|
||||
crypt_sha256,
|
||||
"$5$"
|
||||
},
|
||||
{
|
||||
"sha512",
|
||||
crypt_sha512,
|
||||
"$6$"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
{ "nth", crypt_nthash, "$3$" },
|
||||
{ "sha256", crypt_sha256, "$5$" },
|
||||
#ifdef HAS_DES
|
||||
{ "des", crypt_des, "_" },
|
||||
#endif
|
||||
|
||||
/* sentinel */
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
#ifdef HAS_DES
|
||||
#define CRYPT_DEFAULT "des"
|
||||
#else
|
||||
#define CRYPT_DEFAULT "md5"
|
||||
#endif
|
||||
static const struct crypt_format *crypt_format = &crypt_formats[0];
|
||||
|
||||
static int crypt_type = -1;
|
||||
|
||||
static void
|
||||
crypt_setdefault(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (crypt_type != -1)
|
||||
return;
|
||||
for (i = 0; i < sizeof(crypt_types) / sizeof(crypt_types[0]) - 1; i++) {
|
||||
if (strcmp(CRYPT_DEFAULT, crypt_types[i].name) == 0) {
|
||||
crypt_type = (int)i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
crypt_type = 0;
|
||||
}
|
||||
#define DES_SALT_ALPHABET \
|
||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
/*
|
||||
* Returns the name of the currently selected format.
|
||||
*/
|
||||
const char *
|
||||
crypt_get_format(void)
|
||||
{
|
||||
|
||||
crypt_setdefault();
|
||||
return (crypt_types[crypt_type].name);
|
||||
return (crypt_format->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Selects the format to use for subsequent crypt(3) invocations.
|
||||
*/
|
||||
int
|
||||
crypt_set_format(const char *type)
|
||||
crypt_set_format(const char *format)
|
||||
{
|
||||
size_t i;
|
||||
const struct crypt_format *cf;
|
||||
|
||||
crypt_setdefault();
|
||||
for (i = 0; i < sizeof(crypt_types) / sizeof(crypt_types[0]) - 1; i++) {
|
||||
if (strcmp(type, crypt_types[i].name) == 0) {
|
||||
crypt_type = (int)i;
|
||||
for (cf = crypt_formats; cf->name != NULL; ++cf) {
|
||||
if (strcasecmp(cf->name, format) == 0) {
|
||||
crypt_format = cf;
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hash the given password with the given salt. If the salt begins with a
|
||||
* magic string (e.g. "$6$" for sha512), the corresponding format is used;
|
||||
* otherwise, the currently selected format is used.
|
||||
*/
|
||||
char *
|
||||
crypt(const char *passwd, const char *salt)
|
||||
{
|
||||
size_t i;
|
||||
const struct crypt_format *cf;
|
||||
|
||||
crypt_setdefault();
|
||||
for (i = 0; i < sizeof(crypt_types) / sizeof(crypt_types[0]) - 1; i++) {
|
||||
if (crypt_types[i].magic != NULL && strncmp(salt,
|
||||
crypt_types[i].magic, strlen(crypt_types[i].magic)) == 0)
|
||||
return (crypt_types[i].func(passwd, salt));
|
||||
}
|
||||
return (crypt_types[crypt_type].func(passwd, salt));
|
||||
for (cf = crypt_formats; cf->name != NULL; ++cf)
|
||||
if (cf->magic != NULL && strstr(salt, cf->magic) == salt)
|
||||
return (cf->func(passwd, salt));
|
||||
#ifdef HAS_DES
|
||||
if (strlen(salt) == 13 && strspn(salt, DES_SALT_ALPHABET) == 13)
|
||||
return (crypt_des(passwd, salt));
|
||||
#endif
|
||||
return (crypt_format->func(passwd, salt));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user