Author: des
Date: Sun May 11 15:03:24 2014
New Revision: 265880
URL: http://svnweb.freebsd.org/changeset/base/265880

Log:
  MFH (r233462, r236438): mdoc fixes
  MFH (r261913): switch default to sha512
  MFH (r264964): rewrite so DES still works when not the default
  MFH (r262945): clean up man page

Modified:
  stable/9/lib/libcrypt/crypt.3
  stable/9/lib/libcrypt/crypt.c
Directory Properties:
  stable/9/lib/libcrypt/   (props changed)

Modified: stable/9/lib/libcrypt/crypt.3
==============================================================================
--- stable/9/lib/libcrypt/crypt.3       Sun May 11 14:54:17 2014        
(r265879)
+++ stable/9/lib/libcrypt/crypt.3       Sun May 11 15:03:24 2014        
(r265880)
@@ -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,23 +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:
-.Pp
 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
@@ -128,7 +131,8 @@ The salt is a 9-character array consisti
 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
@@ -139,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
@@ -149,7 +154,8 @@ and
 .Em i+24
 are swapped in the
 .Tn DES
-E-box output).
+E-box output
+.Pc .
 .Pp
 The
 .Tn DES
@@ -158,12 +164,13 @@ key is used to encrypt a 64-bit constant
 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:
-.Pp
+.Ss Modular crypt:
 If the salt begins with the string
 .Fa $digit$
 then the Modular Crypt Format is used.
@@ -172,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:
@@ -198,12 +204,10 @@ SHA-512
 .Pp
 Other crypt formats may be easily added.
 An example salt would be:
-.Bl -tag -offset indent
+.Bl -tag -width 6n -offset indent
 .It Cm "$4$thesalt$rest"
 .El
-.Pp
-.Ss "Traditional" crypt:
-.Pp
+.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.
@@ -220,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

Modified: stable/9/lib/libcrypt/crypt.c
==============================================================================
--- stable/9/lib/libcrypt/crypt.c       Sun May 11 14:54:17 2014        
(r265879)
+++ stable/9/lib/libcrypt/crypt.c       Sun May 11 15:03:24 2014        
(r265880)
@@ -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
-#define CRYPT_DEFAULT  "des"
-#else
-#define CRYPT_DEFAULT  "md5"
+       { "des",        crypt_des,              "_"     },
 #endif
 
-static int crypt_type = -1;
+       /* sentinel */
+       { NULL,         NULL,                   NULL    }
+};
 
-static void
-crypt_setdefault(void)
-{
-       size_t i;
+static const struct crypt_format *crypt_format = &crypt_formats[0];
 
-       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));
 }
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to