aboutsummaryrefslogtreecommitdiff
path: root/manual
diff options
context:
space:
mode:
Diffstat (limited to 'manual')
-rw-r--r--manual/contrib.texi2
-rw-r--r--manual/crypt.texi234
-rw-r--r--manual/examples/genpass.c59
-rw-r--r--manual/examples/testpass.c67
-rw-r--r--manual/users.texi4
5 files changed, 25 insertions, 341 deletions
diff --git a/manual/contrib.texi b/manual/contrib.texi
index 20d9f74..52ebd69 100644
--- a/manual/contrib.texi
+++ b/manual/contrib.texi
@@ -199,7 +199,7 @@ Romain Geissler for various fixes.
@item
Michael Glad for the passphrase-hashing function @code{crypt} and related
-functions.
+functions (no longer part of glibc, but we still appreciate his work).
@item
Wolfram Gloger for contributing the memory allocation functions
diff --git a/manual/crypt.texi b/manual/crypt.texi
index af23dd7..4882ee3 100644
--- a/manual/crypt.texi
+++ b/manual/crypt.texi
@@ -1,205 +1,18 @@
@node Cryptographic Functions, Debugging Support, System Configuration, Top
@chapter Cryptographic Functions
-@c %MENU% Passphrase storage and strongly unpredictable bytes.
+@c %MENU% A few functions to support cryptographic applications
-@Theglibc{} includes only a few special-purpose cryptographic
-functions: one-way hash functions for passphrase storage, and access
-to a cryptographic randomness source, if one is provided by the
-operating system. Programs that need general-purpose cryptography
-should use a dedicated cryptography library, such as
+@Theglibc{} includes only one type of special-purpose cryptographic
+functions; these allow use of a source of cryptographically strong
+pseudorandom numbers, if such a source is provided by the operating
+system. Programs that need general-purpose cryptography should use
+a dedicated cryptography library, such as
@uref{https://www.gnu.org/software/libgcrypt/,,libgcrypt}.
-Many countries place legal restrictions on the import, export,
-possession, or use of cryptographic software. We deplore these
-restrictions, but we must still warn you that @theglibc{} may be
-subject to them, even if you do not use the functions in this chapter
-yourself. The restrictions vary from place to place and are changed
-often, so we cannot give any more specific advice than this warning.
-
@menu
-* Passphrase Storage:: One-way hashing for passphrases.
* Unpredictable Bytes:: Randomness for cryptographic purposes.
@end menu
-@node Passphrase Storage
-@section Passphrase Storage
-@cindex passphrase hashing
-@cindex one-way hashing
-@cindex hashing, passphrase
-
-Sometimes it is necessary to be sure that a user is authorized
-to use some service a machine provides---for instance, to log in as a
-particular user id (@pxref{Users and Groups}). One traditional way of
-doing this is for each user to choose a secret @dfn{passphrase}; then, the
-system can ask someone claiming to be a user what the user's passphrase
-is, and if the person gives the correct passphrase then the system can
-grant the appropriate privileges. (Traditionally, these were called
-``passwords,'' but nowadays a single word is too easy to guess.)
-
-Programs that handle passphrases must take special care not to reveal
-them to anyone, no matter what. It is not enough to keep them in a
-file that is only accessible with special privileges. The file might
-be ``leaked'' via a bug or misconfiguration, and system administrators
-shouldn't learn everyone's passphrase even if they have to edit that
-file for some reason. To avoid this, passphrases should also be
-converted into @dfn{one-way hashes}, using a @dfn{one-way function},
-before they are stored.
-
-A one-way function is easy to compute, but there is no known way to
-compute its inverse. This means the system can easily check
-passphrases, by hashing them and comparing the result with the stored
-hash. But an attacker who discovers someone's passphrase hash can
-only discover the passphrase it corresponds to by guessing and
-checking. The one-way functions are designed to make this process
-impractically slow, for all but the most obvious guesses. (Do not use
-a word from the dictionary as your passphrase.)
-
-@Theglibc{} provides an interface to four one-way functions, based on
-the SHA-2-512, SHA-2-256, MD5, and DES cryptographic primitives. New
-passphrases should be hashed with either of the SHA-based functions.
-The others are too weak for newly set passphrases, but we continue to
-support them for verifying old passphrases. The DES-based hash is
-especially weak, because it ignores all but the first eight characters
-of its input.
-
-@deftypefun {char *} crypt (const char *@var{phrase}, const char *@var{salt})
-@standards{X/Open, unistd.h}
-@standards{GNU, crypt.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}}
-@c Besides the obvious problem of returning a pointer into static
-@c storage, the DES initializer takes an internal lock with the usual
-@c set of problems for AS- and AC-Safety.
-@c The NSS implementations may leak file descriptors if cancelled.
-@c The MD5, SHA256 and SHA512 implementations will malloc on long keys,
-@c and NSS relies on dlopening, which brings about another can of worms.
-
-The function @code{crypt} converts a passphrase string, @var{phrase},
-into a one-way hash suitable for storage in the user database. The
-string that it returns will consist entirely of printable ASCII
-characters. It will not contain whitespace, nor any of the characters
-@samp{:}, @samp{;}, @samp{*}, @samp{!}, or @samp{\}.
-
-The @var{salt} parameter controls which one-way function is used, and
-it also ensures that the output of the one-way function is different
-for every user, even if they have the same passphrase. This makes it
-harder to guess passphrases from a large user database. Without salt,
-the attacker could make a guess, run @code{crypt} on it once, and
-compare the result with all the hashes. Salt forces the attacker to
-make separate calls to @code{crypt} for each user.
-
-To verify a passphrase, pass the previously hashed passphrase as the
-@var{salt}. To hash a new passphrase for storage, set @var{salt} to a
-string consisting of a prefix plus a sequence of randomly chosen
-characters, according to this table:
-
-@multitable @columnfractions .2 .1 .3
-@headitem One-way function @tab Prefix @tab Random sequence
-@item SHA-2-512
-@tab @samp{$6$}
-@tab 16 characters
-@item SHA-2-256
-@tab @samp{$5$}
-@tab 16 characters
-@item MD5
-@tab @samp{$1$}
-@tab 8 characters
-@item DES
-@tab @samp{}
-@tab 2 characters
-@end multitable
-
-In all cases, the random characters should be chosen from the alphabet
-@code{./0-9A-Za-z}.
-
-With all of the hash functions @emph{except} DES, @var{phrase} can be
-arbitrarily long, and all eight bits of each byte are significant.
-With DES, only the first eight characters of @var{phrase} affect the
-output, and the eighth bit of each byte is also ignored.
-
-@code{crypt} can fail. Some implementations return @code{NULL} on
-failure, and others return an @emph{invalid} hashed passphrase, which
-will begin with a @samp{*} and will not be the same as @var{salt}. In
-either case, @code{errno} will be set to indicate the problem. Some
-of the possible error codes are:
-
-@table @code
-@item EINVAL
-@var{salt} is invalid; neither a previously hashed passphrase, nor a
-well-formed new salt for any of the supported hash functions.
-
-@item EPERM
-The system configuration forbids use of the hash function selected by
-@var{salt}.
-
-@item ENOMEM
-Failed to allocate internal scratch storage.
-
-@item ENOSYS
-@itemx EOPNOTSUPP
-Hashing passphrases is not supported at all, or the hash function
-selected by @var{salt} is not supported. @Theglibc{} does not use
-these error codes, but they may be encountered on other operating
-systems.
-@end table
-
-@code{crypt} uses static storage for both internal scratchwork and the
-string it returns. It is not safe to call @code{crypt} from multiple
-threads simultaneously, and the string it returns will be overwritten
-by any subsequent call to @code{crypt}.
-
-@code{crypt} is specified in the X/Open Portability Guide and is
-present on nearly all historical Unix systems. However, the XPG does
-not specify any one-way functions.
-
-@code{crypt} is declared in @file{unistd.h}. @Theglibc{} also
-declares this function in @file{crypt.h}.
-@end deftypefun
-
-@deftypefun {char *} crypt_r (const char *@var{phrase}, const char *@var{salt}, struct crypt_data *@var{data})
-@standards{GNU, crypt.h}
-@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}}
-@tindex struct crypt_data
-@c Compared with crypt, this function fixes the @mtasurace:crypt
-@c problem, but nothing else.
-
-The function @code{crypt_r} is a thread-safe version of @code{crypt}.
-Instead of static storage, it uses the memory pointed to by its
-@var{data} argument for both scratchwork and the string it returns.
-It can safely be used from multiple threads, as long as different
-@var{data} objects are used in each thread. The string it returns
-will still be overwritten by another call with the same @var{data}.
-
-@var{data} must point to a @code{struct crypt_data} object allocated
-by the caller. All of the fields of @code{struct crypt_data} are
-private, but before one of these objects is used for the first time,
-it must be initialized to all zeroes, using @code{memset} or similar.
-After that, it can be reused for many calls to @code{crypt_r} without
-erasing it again. @code{struct crypt_data} is very large, so it is
-best to allocate it with @code{malloc} rather than as a local
-variable. @xref{Memory Allocation}.
-
-@code{crypt_r} is a GNU extension. It is declared in @file{crypt.h},
-as is @code{struct crypt_data}.
-@end deftypefun
-
-The following program shows how to use @code{crypt} the first time a
-passphrase is entered. It uses @code{getentropy} to make the salt as
-unpredictable as possible; @pxref{Unpredictable Bytes}.
-
-@smallexample
-@include genpass.c.texi
-@end smallexample
-
-The next program demonstrates how to verify a passphrase. It checks a
-hash hardcoded into the program, because looking up real users' hashed
-passphrases may require special privileges (@pxref{User Database}).
-It also shows that different one-way functions produce different
-hashes for the same passphrase.
-
-@smallexample
-@include testpass.c.texi
-@end smallexample
-
@node Unpredictable Bytes
@section Generating Unpredictable Bytes
@cindex randomness source
@@ -211,27 +24,24 @@ hashes for the same passphrase.
@cindex CSPRNG
@cindex DRBG
-Cryptographic applications often need some random data that will be as
-difficult as possible for a hostile eavesdropper to guess. For
-instance, encryption keys should be chosen at random, and the ``salt''
-strings used by @code{crypt} (@pxref{Passphrase Storage}) should also
-be chosen at random.
-
-Some pseudo-random number generators do not provide unpredictable-enough
-output for cryptographic applications; @pxref{Pseudo-Random Numbers}.
-Such applications need to use a @dfn{cryptographic random number
-generator} (CRNG), also sometimes called a @dfn{cryptographically strong
-pseudo-random number generator} (CSPRNG) or @dfn{deterministic random
-bit generator} (DRBG).
+Cryptographic applications often need random data that will be as
+difficult as possible for a hostile eavesdropper to guess.
+The pseudo-random number generators provided by @theglibc{}
+(@pxref{Pseudo-Random Numbers}) are not suitable for this purpose.
+They produce output that is @emph{statistically} random, but fails to
+be @emph{unpredictable}. Cryptographic applications require a
+@dfn{cryptographic random number generator} (CRNG), also known as a
+@dfn{cryptographically strong pseudo-random number generator} (CSPRNG)
+or a @dfn{deterministic random bit generator} (DRBG).
Currently, @theglibc{} does not provide a cryptographic random number
-generator, but it does provide functions that read random data from a
-@dfn{randomness source} supplied by the operating system. The
-randomness source is a CRNG at heart, but it also continually
-``re-seeds'' itself from physical sources of randomness, such as
-electronic noise and clock jitter. This means applications do not need
-to do anything to ensure that the random numbers it produces are
-different on each run.
+generator, but it does provide functions that read cryptographically
+strong random data from a @dfn{randomness source} supplied by the
+operating system. This randomness source is a CRNG at heart, but it
+also continually ``re-seeds'' itself from physical sources of
+randomness, such as electronic noise and clock jitter. This means
+applications do not need to do anything to ensure that the random
+numbers it produces are different on each run.
The catch, however, is that these functions will only produce
relatively short random strings in any one call. Often this is not a
diff --git a/manual/examples/genpass.c b/manual/examples/genpass.c
deleted file mode 100644
index e40efc7..0000000
--- a/manual/examples/genpass.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Encrypting Passwords
- Copyright (C) 1991-2023 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <https://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <unistd.h>
-#include <crypt.h>
-
-int
-main(void)
-{
- unsigned char ubytes[16];
- char salt[20];
- const char *const saltchars =
- "./0123456789ABCDEFGHIJKLMNOPQRST"
- "UVWXYZabcdefghijklmnopqrstuvwxyz";
- char *hash;
- int i;
-
- /* Retrieve 16 unpredictable bytes from the operating system. */
- if (getentropy (ubytes, sizeof ubytes))
- {
- perror ("getentropy");
- return 1;
- }
-
- /* Use them to fill in the salt string. */
- salt[0] = '$';
- salt[1] = '5'; /* SHA-256 */
- salt[2] = '$';
- for (i = 0; i < 16; i++)
- salt[3+i] = saltchars[ubytes[i] & 0x3f];
- salt[3+i] = '\0';
-
- /* Read in the user's passphrase and hash it. */
- hash = crypt (getpass ("Enter new passphrase: "), salt);
- if (!hash || hash[0] == '*')
- {
- perror ("crypt");
- return 1;
- }
-
- /* Print the results. */
- puts (hash);
- return 0;
-}
diff --git a/manual/examples/testpass.c b/manual/examples/testpass.c
deleted file mode 100644
index 555fe11..0000000
--- a/manual/examples/testpass.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Verify a passphrase.
- Copyright (C) 1991-2023 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <https://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <crypt.h>
-
-/* @samp{GNU's Not Unix} hashed using SHA-256, MD5, and DES. */
-static const char hash_sha[] =
- "$5$DQ2z5NHf1jNJnChB$kV3ZTR0aUaosujPhLzR84Llo3BsspNSe4/tsp7VoEn6";
-static const char hash_md5[] = "$1$A3TxDv41$rtXVTUXl2LkeSV0UU5xxs1";
-static const char hash_des[] = "FgkTuF98w5DaI";
-
-int
-main(void)
-{
- char *phrase;
- int status = 0;
-
- /* Prompt for a passphrase. */
- phrase = getpass ("Enter passphrase: ");
-
- /* Compare against the stored hashes. Any input that begins with
- @samp{GNU's No} will match the DES hash, but the other two will
- only match @samp{GNU's Not Unix}. */
-
- if (strcmp (crypt (phrase, hash_sha), hash_sha))
- {
- puts ("SHA: not ok");
- status = 1;
- }
- else
- puts ("SHA: ok");
-
- if (strcmp (crypt (phrase, hash_md5), hash_md5))
- {
- puts ("MD5: not ok");
- status = 1;
- }
- else
- puts ("MD5: ok");
-
- if (strcmp (crypt (phrase, hash_des), hash_des))
- {
- puts ("DES: not ok");
- status = 1;
- }
- else
- puts ("DES: ok");
-
- return status;
-}
diff --git a/manual/users.texi b/manual/users.texi
index 72da3fb..4c83f12 100644
--- a/manual/users.texi
+++ b/manual/users.texi
@@ -1731,8 +1731,8 @@ most systems, but on some systems a special network server gives access
to it.
Historically, this database included one-way hashes of user
-passphrases (@pxref{Passphrase Storage}) as well as public information
-about each user (such as their user ID and full name). Many of the
+passphrases, as well as public information about each user
+(such as their user ID and full name). Many of the names of
functions and data structures associated with this database, and the
filename @file{/etc/passwd} itself, reflect this history. However,
the information in this database is available to all users, and it is