crypt: Remove libcrypt support

All the crypt related functions, cryptographic algorithms, and
make requirements are removed,  with only the exception of md5
implementation which is moved to locale folder since it is
required by localedef for integrity protection (libc's
locale-reading code does not check these, but localedef does
generate them).

Besides thec code itself, both internal documentation and the
manual is also adjusted.  This allows to remove both --enable-crypt
and --enable-nss-crypt configure options.

Checked with a build for all affected ABIs.

Co-authored-by: Zack Weinberg <zack@owlfolio.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
Adhemerval Zanella 2023-10-02 09:11:49 -03:00
parent bb2ff12abd
commit e6e3c66688
97 changed files with 61 additions and 5801 deletions

View File

@ -24,21 +24,6 @@ catgets/gencat.c:
catgets/open_catalog.c: catgets/open_catalog.c:
Contributed by Ulrich Drepper, <drepper@gnu.org>. Contributed by Ulrich Drepper, <drepper@gnu.org>.
crypt/md5-crypt.c:
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
crypt/sha256-crypt.c:
Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
crypt/sha256.c:
Written by Ulrich Drepper <drepper@redhat.com>, 2007.
crypt/sha512-crypt.c:
Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
crypt/sha512.c:
Written by Ulrich Drepper <drepper@redhat.com>, 2007.
debug/backtrace.c: debug/backtrace.c:
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.

13
INSTALL
View File

@ -228,19 +228,6 @@ if CFLAGS is specified it must enable optimization. For example:
By default for x86_64, the GNU C Library is built with the vector By default for x86_64, the GNU C Library is built with the vector
math library. Use this option to disable the vector math library. math library. Use this option to disable the vector math library.
--enable-crypt
Install the legacy passphrase-hashing library libcrypt and the
header file crypt.h. unistd.h will declare the function
crypt regardless of this option. Using this option does not
change the set of programs that may need to be linked with
-lcrypt; it only means that the GNU C Library will provide that
library.
This option is for hackers and distributions who may not yet be
able to use libcrypt alternatives such as libxcrypt and need this
legacy implementation as a temporary workaround. Note that
libcrypt may be removed in a future release.
--disable-scv --disable-scv
Disable using scv instruction for syscalls. All syscalls will Disable using scv instruction for syscalls. All syscalls will
use sc instead, even if the kernel supports scv. PowerPC only. use sc instead, even if the kernel supports scv. PowerPC only.

View File

@ -1357,11 +1357,6 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal \
localedata timezone rt conform debug mathvec support \ localedata timezone rt conform debug mathvec support \
dlfcn elf dlfcn elf
ifeq ($(build-crypt),yes)
all-subdirs += crypt
rpath-dirs += crypt
endif
ifndef avoid-generated ifndef avoid-generated
# sysd-sorted itself will contain rules making the sysd-sorted target # sysd-sorted itself will contain rules making the sysd-sorted target
# depend on Depend files. But if you just added a Depend file to an # depend on Depend files. But if you just added a Depend file to an

16
NEWS
View File

@ -44,6 +44,22 @@ Deprecated and removed features, and other changes affecting compatibility:
".tmp", to avoid examining temporary files created by the RPM and dpkg ".tmp", to avoid examining temporary files created by the RPM and dpkg
package managers. package managers.
* libcrypt has been removed from the GNU C Library. The configure
options "--enable-crypt" and "--enable-nss-crypt" are no longer
available. <crypt.h>, libcrypt.a, and libcrypt.so.1 will not be
installed, and <unistd.h> will not declare the crypt function.
The replacement for libcrypt is libxcrypt, maintained separately from
GNU libc, but available under compatible licensing terms, and providing
binary backward compatibility with the former libcrypt. It is currently
distributed from <https://github.com/besser82/libxcrypt/>.
As a consequence of this removal, GNU libc no longer makes any use of
the NSS cryptography library (Network Security Services; not to be
confused with Name Service Switch). Distributors of binary packages
of GNU libc are advised to check whether their build processes can be
simplified.
Changes to build and runtime requirements: Changes to build and runtime requirements:
* Building on LoongArch requires at a minimum binutils 2.41 for vector * Building on LoongArch requires at a minimum binutils 2.41 for vector

View File

@ -27,8 +27,6 @@ gnulib:
argp/argp-pvh.c argp/argp-pvh.c
argp/argp-xinl.c argp/argp-xinl.c
argp/argp.h argp/argp.h
crypt/md5.c
crypt/md5.h
dirent/alphasort.c dirent/alphasort.c
dirent/scandir.c dirent/scandir.c
# Merged from gnulib 2021-09-21 # Merged from gnulib 2021-09-21

View File

@ -80,16 +80,12 @@ mach-interface-list = @mach_interface_list@
memory-tagging = @memory_tagging@ memory-tagging = @memory_tagging@
nss-crypt = @libc_cv_nss_crypt@
static-nss-crypt = @libc_cv_static_nss_crypt@
# Configuration options. # Configuration options.
build-shared = @shared@ build-shared = @shared@
build-profile = @profile@ build-profile = @profile@
build-static-nss = @static_nss@ build-static-nss = @static_nss@
cross-compiling = @cross_compiling@ cross-compiling = @cross_compiling@
force-install = @force_install@ force-install = @force_install@
build-crypt = @build_crypt@
build-nscd = @build_nscd@ build-nscd = @build_nscd@
use-nscd = @use_nscd@ use-nscd = @use_nscd@
build-hardcoded-path-in-tests= @hardcoded_path_in_tests@ build-hardcoded-path-in-tests= @hardcoded_path_in_tests@

126
configure vendored
View File

@ -700,9 +700,6 @@ INSTALL_PROGRAM
base_machine base_machine
build_pt_chown build_pt_chown
build_nscd build_nscd
libc_cv_static_nss_crypt
libc_cv_nss_crypt
build_crypt
memory_tagging memory_tagging
enable_werror enable_werror
force_install force_install
@ -806,8 +803,6 @@ enable_kernel
enable_werror enable_werror
enable_multi_arch enable_multi_arch
enable_memory_tagging enable_memory_tagging
enable_crypt
enable_nss_crypt
enable_systemtap enable_systemtap
enable_build_nscd enable_build_nscd
enable_nscd enable_nscd
@ -1481,9 +1476,6 @@ Optional Features:
architectures architectures
--enable-memory-tagging enable memory tagging if supported by the --enable-memory-tagging enable memory tagging if supported by the
architecture [default=no] architecture [default=no]
--enable-crypt build and install the legacy passphrase hashing
library, libcrypt
--enable-nss-crypt enable libcrypt to use nss
--enable-systemtap enable systemtap static probe points [default=no] --enable-systemtap enable systemtap static probe points [default=no]
--disable-build-nscd disable building and installing the nscd daemon --disable-build-nscd disable building and installing the nscd daemon
--disable-nscd library functions will not contact the nscd daemon --disable-nscd library functions will not contact the nscd daemon
@ -4561,124 +4553,6 @@ if test "$memory_tagging" = yes; then
fi fi
# Check whether --enable-crypt was given.
if test ${enable_crypt+y}
then :
enableval=$enable_crypt; build_crypt=$enableval
else $as_nop
build_crypt=no
fi
# Check whether --enable-nss-crypt was given.
if test ${enable_nss_crypt+y}
then :
enableval=$enable_nss_crypt; nss_crypt=$enableval
else $as_nop
nss_crypt=no
fi
if test x$build_libcrypt = xno && test x$nss_crypt = xyes; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-nss-crypt has no effect when libcrypt is disabled" >&5
printf "%s\n" "$as_me: WARNING: --enable-nss-crypt has no effect when libcrypt is disabled" >&2;}
nss_crypt=no
fi
if test x$nss_crypt = xyes; then
nss_includes=-I$(nss-config --includedir 2>/dev/null)
if test $? -ne 0; then
as_fn_error $? "cannot find include directory with nss-config" "$LINENO" 5
fi
nspr_includes=-I$(nspr-config --includedir 2>/dev/null)
if test $? -ne 0; then
as_fn_error $? "cannot find include directory with nspr-config" "$LINENO" 5
fi
old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $nss_includes $nspr_includes"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
typedef int PRBool;
#include <hasht.h>
#include <nsslowhash.h>
void f (void) { NSSLOW_Init (); }
int
main (void)
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
libc_cv_nss_crypt=yes
else $as_nop
as_fn_error $? "
cannot find NSS headers with lowlevel hash function interfaces" "$LINENO" 5
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
old_LIBS="$LIBS"
old_LDFLAGS="$LDFLAGS"
LIBS="$LIBS -lfreebl3"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
typedef int PRBool;
#include <hasht.h>
#include <nsslowhash.h>
int
main (void)
{
NSSLOW_Init();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
libc_cv_nss_crypt=yes
else $as_nop
as_fn_error $? "
cannot link program using lowlevel NSS hash functions" "$LINENO" 5
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
# Check to see if there is a static NSS cryptographic library.
# If there isn't then we can't link anything with libcrypt.a,
# and that might mean disabling some static tests.
LDFLAGS="$LDFLAGS -static"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
typedef int PRBool;
#include <hasht.h>
#include <nsslowhash.h>
int
main (void)
{
NSSLOW_Init();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
libc_cv_static_nss_crypt=yes
else $as_nop
libc_cv_static_nss_crypt=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LDFLAGS="$old_LDFLAGS"
CFLAGS="$old_CFLAGS"
LIBS="$old_LIBS"
else
libc_cv_nss_crypt=no
libc_cv_static_nss_crypt=no
fi
# Check whether --enable-systemtap was given. # Check whether --enable-systemtap was given.
if test ${enable_systemtap+y} if test ${enable_systemtap+y}
then : then :

View File

@ -305,71 +305,6 @@ if test "$memory_tagging" = yes; then
fi fi
AC_SUBST(memory_tagging) AC_SUBST(memory_tagging)
AC_ARG_ENABLE([crypt],
AS_HELP_STRING([--enable-crypt],
[build and install the legacy passphrase hashing library, libcrypt]),
[build_crypt=$enableval],
[build_crypt=no])
AC_SUBST(build_crypt)
AC_ARG_ENABLE([nss-crypt],
AS_HELP_STRING([--enable-nss-crypt],
[enable libcrypt to use nss]),
[nss_crypt=$enableval],
[nss_crypt=no])
if test x$build_libcrypt = xno && test x$nss_crypt = xyes; then
AC_MSG_WARN([--enable-nss-crypt has no effect when libcrypt is disabled])
nss_crypt=no
fi
if test x$nss_crypt = xyes; then
nss_includes=-I$(nss-config --includedir 2>/dev/null)
if test $? -ne 0; then
AC_MSG_ERROR([cannot find include directory with nss-config])
fi
nspr_includes=-I$(nspr-config --includedir 2>/dev/null)
if test $? -ne 0; then
AC_MSG_ERROR([cannot find include directory with nspr-config])
fi
old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $nss_includes $nspr_includes"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([typedef int PRBool;
#include <hasht.h>
#include <nsslowhash.h>
void f (void) { NSSLOW_Init (); }])],
libc_cv_nss_crypt=yes,
AC_MSG_ERROR([
cannot find NSS headers with lowlevel hash function interfaces]))
old_LIBS="$LIBS"
old_LDFLAGS="$LDFLAGS"
LIBS="$LIBS -lfreebl3"
AC_LINK_IFELSE([AC_LANG_PROGRAM([typedef int PRBool;
#include <hasht.h>
#include <nsslowhash.h>],
[NSSLOW_Init();])],
libc_cv_nss_crypt=yes,
AC_MSG_ERROR([
cannot link program using lowlevel NSS hash functions]))
# Check to see if there is a static NSS cryptographic library.
# If there isn't then we can't link anything with libcrypt.a,
# and that might mean disabling some static tests.
LDFLAGS="$LDFLAGS -static"
AC_LINK_IFELSE([AC_LANG_PROGRAM([typedef int PRBool;
#include <hasht.h>
#include <nsslowhash.h>],
[NSSLOW_Init();])],
libc_cv_static_nss_crypt=yes,
libc_cv_static_nss_crypt=no)
LDFLAGS="$old_LDFLAGS"
CFLAGS="$old_CFLAGS"
LIBS="$old_LIBS"
else
libc_cv_nss_crypt=no
libc_cv_static_nss_crypt=no
fi
AC_SUBST(libc_cv_nss_crypt)
AC_SUBST(libc_cv_static_nss_crypt)
AC_ARG_ENABLE([systemtap], AC_ARG_ENABLE([systemtap],
[AS_HELP_STRING([--enable-systemtap], [AS_HELP_STRING([--enable-systemtap],
[enable systemtap static probe points @<:@default=no@:>@])], [enable systemtap static probe points @<:@default=no@:>@])],

View File

@ -212,11 +212,6 @@ linknamespace-libs-XOPEN2K8 = $(linknamespace-libs-xsi)
linknamespace-libs = $(foreach std,$(conformtest-standards),\ linknamespace-libs = $(foreach std,$(conformtest-standards),\
$(linknamespace-libs-$(std))) $(linknamespace-libs-$(std)))
ifeq ($(build-crypt),yes)
linknamespace-libs-xsi += $(common-objpfx)crypt/libcrypt.a
linknamespace-libs-XPG4 += $(common-objpfx)crypt/libcrypt.a
endif
$(linknamespace-symlist-stdlibs-tests): $(objpfx)symlist-stdlibs-%: \ $(linknamespace-symlist-stdlibs-tests): $(objpfx)symlist-stdlibs-%: \
$(linknamespace-libs) $(linknamespace-libs)
LC_ALL=C $(READELF) -W -s $(linknamespace-libs-$*) > $@; \ LC_ALL=C $(READELF) -W -s $(linknamespace-libs-$*) > $@; \

View File

@ -1,69 +0,0 @@
# Copyright (C) 1996-2023 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# The GNU C Library 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
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with the GNU C Library; if not, see
# <https://www.gnu.org/licenses/>.
#
# Sub-makefile for crypt() portion of the library.
#
subdir := crypt
include ../Makeconfig
headers := crypt.h
extra-libs := libcrypt
extra-libs-others := $(extra-libs)
libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
crypt_util
tests := cert md5c-test sha256c-test sha512c-test badsalttest
ifeq ($(nss-crypt),yes)
nss-cpp-flags := -DUSE_NSS \
-I$(shell nss-config --includedir) -I$(shell nspr-config --includedir)
CPPFLAGS-sha256-crypt.c += $(nss-cpp-flags)
CPPFLAGS-sha512-crypt.c += $(nss-cpp-flags)
CPPFLAGS-md5-crypt.c += $(nss-cpp-flags)
LDLIBS-crypt.so = -lfreebl3
else
libcrypt-routines += md5 sha256 sha512
tests += md5test sha256test sha512test
# The test md5test-giant uses up to 400 MB of RSS and runs on a fast
# machine over a minute.
xtests = md5test-giant
endif
include ../Rules
ifneq ($(nss-crypt),yes)
md5-routines := md5 $(filter md5%,$(libcrypt-sysdep_routines))
sha256-routines := sha256 $(filter sha256%,$(libcrypt-sysdep_routines))
sha512-routines := sha512 $(filter sha512%,$(libcrypt-sysdep_routines))
$(objpfx)md5test: $(patsubst %, $(objpfx)%.o,$(md5-routines))
$(objpfx)md5test-giant: $(patsubst %, $(objpfx)%.o,$(md5-routines))
$(objpfx)sha256test: $(patsubst %, $(objpfx)%.o,$(sha256-routines))
$(objpfx)sha512test: $(patsubst %, $(objpfx)%.o,$(sha512-routines))
endif
ifeq (yes,$(build-shared))
$(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.so
else
$(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.a
endif

View File

@ -1,135 +0,0 @@
The following is the README for UFC-crypt, with those portions deleted
that are known to be incorrect for the implementation used with the
GNU C library.
UFC-crypt: ultra fast 'crypt' implementation
============================================
@(#)README 2.27 11 Sep 1996
Design goals/non goals:
----------------------
- Crypt implementation plugin compatible with crypt(3)/fcrypt.
- High performance when used for password cracking.
- Portable to most 32/64 bit machines.
- Startup time/mixed salt performance not critical.
Features of the implementation:
------------------------------
- On most machines, UFC-crypt runs 30-60 times faster than crypt(3) when
invoked repeated times with the same salt and varying passwords.
- With mostly constant salts, performance is about two to three times
that of the default fcrypt implementation shipped with Alec
Muffets 'Crack' password cracker. For instructions on how to
plug UFC-crypt into 'Crack', see below.
- With alternating salts, performance is only about twice
that of crypt(3).
- Requires 165 kb for tables.
Author & licensing etc
----------------------
UFC-crypt is created by Michael Glad, email: glad@daimi.aau.dk, and has
been donated to the Free Software Foundation, Inc. It is covered by the
GNU library license version 2, see the file 'COPYING.LIB'.
NOTES FOR USERS OUTSIDE THE US:
------------------------------
The US government limits the export of DES based software/hardware.
This software is written in Aarhus, Denmark. It can therefore be retrieved
from ftp sites outside the US without breaking US law. Please do not
ftp it from american sites.
Benchmark table:
---------------
The table shows how many operations per second UFC-crypt can
do on various machines.
|--------------|-------------------------------------------|
|Machine | SUN* SUN* HP* DecStation HP |
| | 3/50 ELC 9000/425e 3100 9000/720 |
|--------------|-------------------------------------------|
| Crypt(3)/sec | 4.6 30 15 25 57 |
| Ufc/sec | 220 990 780 1015 3500 |
|--------------|-------------------------------------------|
| Speedup | 48 30 52 40 60 |
|--------------|-------------------------------------------|
*) Compiled using special assembly language support module.
It seems as if performance is limited by CPU bus and data cache capacity.
This also makes the benchmarks debatable compared to a real test with
UFC-crypt wired into Crack. However, the table gives an outline of
what can be expected.
Optimizations:
-------------
Here are the optimizations used relative to an ordinary implementation
such as the one said to be used in crypt(3).
Major optimizations
*******************
- Keep data packed as bits in integer variables -- allows for
fast permutations & parallel xor's in CPU hardware.
- Let adjacent final & initial permutations collapse.
- Keep working data in 'E expanded' format all the time.
- Implement DES 'f' function mostly by table lookup
- Calculate the above function on 12 bit basis rather than 6
as would be the most natural.
- Implement setup routines so that performance is limited by the DES
inner loops only.
- Instead of doing salting in the DES inner loops, modify the above tables
each time a new salt is seen. According to the BSD crypt code this is
ugly :-)
Minor (dirty) optimizations
***************************
- combine iterations of DES inner loop so that DES only loops
8 times. This saves a lot of variable swapping.
- Implement key access by a walking pointer rather than coding
as array indexing.
- As described, the table based f function uses a 3 dimensional array:
sb ['number of 12 bit segment']['12 bit index']['48 bit half index']
Code the routine with 4 (one dimensional) vectors.
- Design the internal data format & uglify the DES loops so that
the compiler does not need to do bit shifts when indexing vectors.
Revision history
****************
UFC patchlevel 0: base version; released to alt.sources on Sep 24 1991
UFC patchlevel 1: patch released to alt.sources on Sep 27 1991.
No longer rebuilds sb tables when seeing a new salt.
UFC-crypt pl0: Essentially UFC pl 1. Released to comp.sources.misc
on Oct 22 1991.
UFC-crypt pl1: Released to comp.sources.misc in march 1992
* setkey/encrypt routines added
* added validation/benchmarking programs
* reworked keyschedule setup code
* memory demands reduced
* 64 bit support added

View File

@ -1,5 +0,0 @@
libcrypt {
GLIBC_2.0 {
crypt; crypt_r; encrypt; encrypt_r; fcrypt; setkey; setkey_r;
}
}

View File

@ -1,54 +0,0 @@
/* Test program for bad DES salt detection in crypt.
Copyright (C) 2012-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <array_length.h>
#include <stddef.h>
#include <crypt.h>
#include <support/check.h>
static const char *tests[][2] =
{
{ "no salt", "" },
{ "single char", "/" },
{ "first char bad", "!x" },
{ "second char bad", "Z%" },
{ "both chars bad", ":@" },
{ "unsupported algorithm", "$2$" },
{ "unsupported_algorithm", "_1" },
};
static int
do_test (void)
{
struct crypt_data cd;
/* Mark cd as initialized before first call to crypt_r. */
cd.initialized = 0;
for (size_t i = 0; i < array_length (tests); i++)
{
TEST_VERIFY (crypt (tests[i][0], tests[i][1]) == NULL);
TEST_VERIFY (crypt_r (tests[i][0], tests[i][1], &cd) == NULL);
}
return 0;
}
#include <support/test-driver.c>

View File

@ -1,135 +0,0 @@
/*
* This crypt(3) validation program shipped with UFC-crypt
* is derived from one distributed with Phil Karns PD DES package.
*
* @(#)cert.c 1.8 11 Aug 1996
*/
#include <stdio.h>
#include <stdlib.h>
#include "crypt.h"
/* This file tests the deprecated setkey/encrypt interface. */
#include <shlib-compat.h>
#if TEST_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
#define libcrypt_version_reference(symbol, version) \
_libcrypt_version_reference (symbol, VERSION_libcrypt_##version)
#define _libcrypt_version_reference(symbol, version) \
__libcrypt_version_reference (symbol, version)
#define __libcrypt_version_reference(symbol, version) \
__asm__ (".symver " #symbol ", " #symbol "@" #version)
extern void setkey (const char *);
extern void encrypt (const char *, int);
libcrypt_version_reference (setkey, GLIBC_2_0);
libcrypt_version_reference (encrypt, GLIBC_2_0);
int totfails = 0;
int main (int argc, char *argv[]);
void get8 (char *cp);
void put8 (char *cp);
void good_bye (void) __attribute__ ((noreturn));
void
good_bye (void)
{
if(totfails == 0) {
printf("Passed DES validation suite\n");
exit(0);
} else {
printf("%d failures during DES validation suite!!!\n", totfails);
exit(1);
}
}
int
main (int argc, char *argv[])
{
char key[64],plain[64],cipher[64],answer[64];
int i;
int fail;
for(;!feof(stdin);){
get8(key);
printf(" K: "); put8(key);
setkey(key);
get8(plain);
printf(" P: "); put8(plain);
get8(answer);
printf(" C: "); put8(answer);
for(i=0;i<64;i++)
cipher[i] = plain[i];
encrypt(cipher, 0);
for(i=0;i<64;i++)
if(cipher[i] != answer[i])
break;
fail = 0;
if(i != 64){
printf(" Encrypt FAIL");
fail++; totfails++;
}
encrypt(cipher, 1);
for(i=0;i<64;i++)
if(cipher[i] != plain[i])
break;
if(i != 64){
printf(" Decrypt FAIL");
fail++; totfails++;
}
if(fail == 0)
printf(" OK");
printf("\n");
}
good_bye();
}
void
get8 (char *cp)
{
int i,j,t;
for(i=0;i<8;i++){
if (scanf("%2x",&t) < 1)
{
if(ferror(stdin))
totfails++;
}
if(feof(stdin))
good_bye();
for(j=0; j<8 ; j++) {
*cp++ = (t & (0x01 << (7-j))) != 0;
}
}
}
void
put8 (char *cp)
{
int i,j,t;
for(i=0;i<8;i++){
t = 0;
for(j = 0; j<8; j++)
t = (t<<1) | *cp++;
printf("%02x", t);
}
}
#else /* encrypt and setkey are not available. */
int
main (void)
{
return 77; /* UNSUPPORTED */
}
#endif

View File

@ -1,171 +0,0 @@
0101010101010101 95f8a5e5dd31d900 8000000000000000
0101010101010101 dd7f121ca5015619 4000000000000000
0101010101010101 2e8653104f3834ea 2000000000000000
0101010101010101 4bd388ff6cd81d4f 1000000000000000
0101010101010101 20b9e767b2fb1456 0800000000000000
0101010101010101 55579380d77138ef 0400000000000000
0101010101010101 6cc5defaaf04512f 0200000000000000
0101010101010101 0d9f279ba5d87260 0100000000000000
0101010101010101 d9031b0271bd5a0a 0080000000000000
0101010101010101 424250b37c3dd951 0040000000000000
0101010101010101 b8061b7ecd9a21e5 0020000000000000
0101010101010101 f15d0f286b65bd28 0010000000000000
0101010101010101 add0cc8d6e5deba1 0008000000000000
0101010101010101 e6d5f82752ad63d1 0004000000000000
0101010101010101 ecbfe3bd3f591a5e 0002000000000000
0101010101010101 f356834379d165cd 0001000000000000
0101010101010101 2b9f982f20037fa9 0000800000000000
0101010101010101 889de068a16f0be6 0000400000000000
0101010101010101 e19e275d846a1298 0000200000000000
0101010101010101 329a8ed523d71aec 0000100000000000
0101010101010101 e7fce22557d23c97 0000080000000000
0101010101010101 12a9f5817ff2d65d 0000040000000000
0101010101010101 a484c3ad38dc9c19 0000020000000000
0101010101010101 fbe00a8a1ef8ad72 0000010000000000
0101010101010101 750d079407521363 0000008000000000
0101010101010101 64feed9c724c2faf 0000004000000000
0101010101010101 f02b263b328e2b60 0000002000000000
0101010101010101 9d64555a9a10b852 0000001000000000
0101010101010101 d106ff0bed5255d7 0000000800000000
0101010101010101 e1652c6b138c64a5 0000000400000000
0101010101010101 e428581186ec8f46 0000000200000000
0101010101010101 aeb5f5ede22d1a36 0000000100000000
0101010101010101 e943d7568aec0c5c 0000000080000000
0101010101010101 df98c8276f54b04b 0000000040000000
0101010101010101 b160e4680f6c696f 0000000020000000
0101010101010101 fa0752b07d9c4ab8 0000000010000000
0101010101010101 ca3a2b036dbc8502 0000000008000000
0101010101010101 5e0905517bb59bcf 0000000004000000
0101010101010101 814eeb3b91d90726 0000000002000000
0101010101010101 4d49db1532919c9f 0000000001000000
0101010101010101 25eb5fc3f8cf0621 0000000000800000
0101010101010101 ab6a20c0620d1c6f 0000000000400000
0101010101010101 79e90dbc98f92cca 0000000000200000
0101010101010101 866ecedd8072bb0e 0000000000100000
0101010101010101 8b54536f2f3e64a8 0000000000080000
0101010101010101 ea51d3975595b86b 0000000000040000
0101010101010101 caffc6ac4542de31 0000000000020000
0101010101010101 8dd45a2ddf90796c 0000000000010000
0101010101010101 1029d55e880ec2d0 0000000000008000
0101010101010101 5d86cb23639dbea9 0000000000004000
0101010101010101 1d1ca853ae7c0c5f 0000000000002000
0101010101010101 ce332329248f3228 0000000000001000
0101010101010101 8405d1abe24fb942 0000000000000800
0101010101010101 e643d78090ca4207 0000000000000400
0101010101010101 48221b9937748a23 0000000000000200
0101010101010101 dd7c0bbd61fafd54 0000000000000100
0101010101010101 2fbc291a570db5c4 0000000000000080
0101010101010101 e07c30d7e4e26e12 0000000000000040
0101010101010101 0953e2258e8e90a1 0000000000000020
0101010101010101 5b711bc4ceebf2ee 0000000000000010
0101010101010101 cc083f1e6d9e85f6 0000000000000008
0101010101010101 d2fd8867d50d2dfe 0000000000000004
0101010101010101 06e7ea22ce92708f 0000000000000002
0101010101010101 166b40b44aba4bd6 0000000000000001
8001010101010101 0000000000000000 95a8d72813daa94d
4001010101010101 0000000000000000 0eec1487dd8c26d5
2001010101010101 0000000000000000 7ad16ffb79c45926
1001010101010101 0000000000000000 d3746294ca6a6cf3
0801010101010101 0000000000000000 809f5f873c1fd761
0401010101010101 0000000000000000 c02faffec989d1fc
0201010101010101 0000000000000000 4615aa1d33e72f10
0180010101010101 0000000000000000 2055123350c00858
0140010101010101 0000000000000000 df3b99d6577397c8
0120010101010101 0000000000000000 31fe17369b5288c9
0110010101010101 0000000000000000 dfdd3cc64dae1642
0108010101010101 0000000000000000 178c83ce2b399d94
0104010101010101 0000000000000000 50f636324a9b7f80
0102010101010101 0000000000000000 a8468ee3bc18f06d
0101800101010101 0000000000000000 a2dc9e92fd3cde92
0101400101010101 0000000000000000 cac09f797d031287
0101200101010101 0000000000000000 90ba680b22aeb525
0101100101010101 0000000000000000 ce7a24f350e280b6
0101080101010101 0000000000000000 882bff0aa01a0b87
0101040101010101 0000000000000000 25610288924511c2
0101020101010101 0000000000000000 c71516c29c75d170
0101018001010101 0000000000000000 5199c29a52c9f059
0101014001010101 0000000000000000 c22f0a294a71f29f
0101012001010101 0000000000000000 ee371483714c02ea
0101011001010101 0000000000000000 a81fbd448f9e522f
0101010801010101 0000000000000000 4f644c92e192dfed
0101010401010101 0000000000000000 1afa9a66a6df92ae
0101010201010101 0000000000000000 b3c1cc715cb879d8
0101010180010101 0000000000000000 19d032e64ab0bd8b
0101010140010101 0000000000000000 3cfaa7a7dc8720dc
0101010120010101 0000000000000000 b7265f7f447ac6f3
0101010110010101 0000000000000000 9db73b3c0d163f54
0101010108010101 0000000000000000 8181b65babf4a975
0101010104010101 0000000000000000 93c9b64042eaa240
0101010102010101 0000000000000000 5570530829705592
0101010101800101 0000000000000000 8638809e878787a0
0101010101400101 0000000000000000 41b9a79af79ac208
0101010101200101 0000000000000000 7a9be42f2009a892
0101010101100101 0000000000000000 29038d56ba6d2745
0101010101080101 0000000000000000 5495c6abf1e5df51
0101010101040101 0000000000000000 ae13dbd561488933
0101010101020101 0000000000000000 024d1ffa8904e389
0101010101018001 0000000000000000 d1399712f99bf02e
0101010101014001 0000000000000000 14c1d7c1cffec79e
0101010101012001 0000000000000000 1de5279dae3bed6f
0101010101011001 0000000000000000 e941a33f85501303
0101010101010801 0000000000000000 da99dbbc9a03f379
0101010101010401 0000000000000000 b7fc92f91d8e92e9
0101010101010201 0000000000000000 ae8e5caa3ca04e85
0101010101010180 0000000000000000 9cc62df43b6eed74
0101010101010140 0000000000000000 d863dbb5c59a91a0
0101010101010120 0000000000000000 a1ab2190545b91d7
0101010101010110 0000000000000000 0875041e64c570f7
0101010101010108 0000000000000000 5a594528bebef1cc
0101010101010104 0000000000000000 fcdb3291de21f0c0
0101010101010102 0000000000000000 869efd7f9f265a09
1046913489980131 0000000000000000 88d55e54f54c97b4
1007103489988020 0000000000000000 0c0cc00c83ea48fd
10071034c8980120 0000000000000000 83bc8ef3a6570183
1046103489988020 0000000000000000 df725dcad94ea2e9
1086911519190101 0000000000000000 e652b53b550be8b0
1086911519580101 0000000000000000 af527120c485cbb0
5107b01519580101 0000000000000000 0f04ce393db926d5
1007b01519190101 0000000000000000 c9f00ffc74079067
3107915498080101 0000000000000000 7cfd82a593252b4e
3107919498080101 0000000000000000 cb49a2f9e91363e3
10079115b9080140 0000000000000000 00b588be70d23f56
3107911598080140 0000000000000000 406a9a6ab43399ae
1007d01589980101 0000000000000000 6cb773611dca9ada
9107911589980101 0000000000000000 67fd21c17dbb5d70
9107d01589190101 0000000000000000 9592cb4110430787
1007d01598980120 0000000000000000 a6b7ff68a318ddd3
1007940498190101 0000000000000000 4d102196c914ca16
0107910491190401 0000000000000000 2dfa9f4573594965
0107910491190101 0000000000000000 b46604816c0e0774
0107940491190401 0000000000000000 6e7e6221a4f34e87
19079210981a0101 0000000000000000 aa85e74643233199
1007911998190801 0000000000000000 2e5a19db4d1962d6
10079119981a0801 0000000000000000 23a866a809d30894
1007921098190101 0000000000000000 d812d961f017d320
100791159819010b 0000000000000000 055605816e58608f
1004801598190101 0000000000000000 abd88e8b1b7716f1
1004801598190102 0000000000000000 537ac95be69da1e1
1004801598190108 0000000000000000 aed0f6ae3c25cdd8
1002911598100104 0000000000000000 b3e35a5ee53e7b8d
1002911598190104 0000000000000000 61c79c71921a2ef8
1002911598100201 0000000000000000 e2f5728f0995013c
1002911698100101 0000000000000000 1aeac39a61f0a464
7ca110454a1a6e57 01a1d6d039776742 690f5b0d9a26939b
0131d9619dc1376e 5cd54ca83def57da 7a389d10354bd271
07a1133e4a0b2686 0248d43806f67172 868ebb51cab4599a
3849674c2602319e 51454b582ddf440a 7178876e01f19b2a
04b915ba43feb5b6 42fd443059577fa2 af37fb421f8c4095
0113b970fd34f2ce 059b5e0851cf143a 86a560f10ec6d85b
0170f175468fb5e6 0756d8e0774761d2 0cd3da020021dc09
43297fad38e373fe 762514b829bf486a ea676b2cb7db2b7a
07a7137045da2a16 3bdd119049372802 dfd64a815caf1a0f
04689104c2fd3b2f 26955f6835af609a 5c513c9c4886c088
37d06bb516cb7546 164d5e404f275232 0a2aeeae3ff4ab77
1f08260d1ac2465e 6b056e18759f5cca ef1bf03e5dfa575a
584023641aba6176 004bd6ef09176062 88bf0db6d70dee56
025816164629b007 480d39006ee762f2 a1f9915541020b56
49793ebc79b3258f 437540c8698f3cfa 6fbf1cafcffd0556
4fb05e1515ab73a7 072d43a077075292 2f22e49bab7ca1ac
49e95d6d4ca229bf 02fe55778117f12a 5a6b612cc26cce4a
018310dc409b26d6 1d9d5c5018f728c2 5f4c038ed12b2e41
1c587f1c13924fef 305532286d6f295a 63fac0d034d9f793

View File

@ -1,183 +0,0 @@
/*
* UFC-crypt: ultra fast crypt(3) implementation
*
* Copyright (C) 1991-2023 Free Software Foundation, Inc.
*
* The GNU C Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* The GNU C Library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the GNU C Library; if not, see
* <https://www.gnu.org/licenses/>.
*
* crypt entry points
*
* @(#)crypt-entry.c 1.2 12/20/96
*
*/
#ifdef DEBUG
#include <stdio.h>
#endif
#include <string.h>
#include <errno.h>
#include <fips-private.h>
#ifndef STATIC
#define STATIC static
#endif
#include "crypt-private.h"
#include <shlib-compat.h>
/* Prototypes for local functions. */
#ifndef __GNU_LIBRARY__
void _ufc_clearmem (char *start, int cnt);
#else
#define _ufc_clearmem(start, cnt) memset(start, 0, cnt)
#endif
extern char *__md5_crypt_r (const char *key, const char *salt, char *buffer,
int buflen);
extern char *__md5_crypt (const char *key, const char *salt);
extern char *__sha256_crypt_r (const char *key, const char *salt,
char *buffer, int buflen);
extern char *__sha256_crypt (const char *key, const char *salt);
extern char *__sha512_crypt_r (const char *key, const char *salt,
char *buffer, int buflen);
extern char *__sha512_crypt (const char *key, const char *salt);
/* Define our magic string to mark salt for MD5 encryption
replacement. This is meant to be the same as for other MD5 based
encryption implementations. */
static const char md5_salt_prefix[] = "$1$";
/* Magic string for SHA256 encryption. */
static const char sha256_salt_prefix[] = "$5$";
/* Magic string for SHA512 encryption. */
static const char sha512_salt_prefix[] = "$6$";
/* For use by the old, non-reentrant routines (crypt/encrypt/setkey) */
extern struct crypt_data _ufc_foobar;
/*
* UNIX crypt function
*/
char *
__crypt_r (const char *key, const char *salt,
struct crypt_data * __restrict data)
{
ufc_long res[4];
char ktab[9];
ufc_long xx = 25; /* to cope with GCC long long compiler bugs */
#ifdef _LIBC
/* Try to find out whether we have to use MD5 encryption replacement. */
if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
{
/* FIPS rules out MD5 password encryption. */
if (fips_enabled_p ())
{
__set_errno (EPERM);
return NULL;
}
return __md5_crypt_r (key, salt, (char *) data,
sizeof (struct crypt_data));
}
/* Try to find out whether we have to use SHA256 encryption replacement. */
if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
return __sha256_crypt_r (key, salt, (char *) data,
sizeof (struct crypt_data));
/* Try to find out whether we have to use SHA512 encryption replacement. */
if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
return __sha512_crypt_r (key, salt, (char *) data,
sizeof (struct crypt_data));
#endif
/*
* Hack DES tables according to salt
*/
if (!_ufc_setup_salt_r (salt, data))
{
__set_errno (EINVAL);
return NULL;
}
/* FIPS rules out DES password encryption. */
if (fips_enabled_p ())
{
__set_errno (EPERM);
return NULL;
}
/*
* Setup key schedule
*/
_ufc_clearmem (ktab, (int) sizeof (ktab));
(void) strncpy (ktab, key, 8);
_ufc_mk_keytab_r (ktab, data);
/*
* Go for the 25 DES encryptions
*/
_ufc_clearmem ((char*) res, (int) sizeof (res));
_ufc_doit_r (xx, data, &res[0]);
/*
* Do final permutations
*/
_ufc_dofinalperm_r (res, data);
/*
* And convert back to 6 bit ASCII
*/
_ufc_output_conversion_r (res[0], res[1], salt, data);
/*
* Erase key-dependent intermediate data. Data dependent only on
* the salt is not considered sensitive.
*/
explicit_bzero (ktab, sizeof (ktab));
explicit_bzero (data->keysched, sizeof (data->keysched));
explicit_bzero (res, sizeof (res));
return data->crypt_3_buf;
}
weak_alias (__crypt_r, crypt_r)
char *
crypt (const char *key, const char *salt)
{
#ifdef _LIBC
/* Try to find out whether we have to use MD5 encryption replacement. */
if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0
/* Let __crypt_r deal with the error code if FIPS is enabled. */
&& !fips_enabled_p ())
return __md5_crypt (key, salt);
/* Try to find out whether we have to use SHA256 encryption replacement. */
if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
return __sha256_crypt (key, salt);
/* Try to find out whether we have to use SHA512 encryption replacement. */
if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
return __sha512_crypt (key, salt);
#endif
return __crypt_r (key, salt, &_ufc_foobar);
}
#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
weak_alias (crypt, fcrypt)
compat_symbol (libcrypt, fcrypt, fcrypt, GLIBC_2_0);
#endif

View File

@ -1,76 +0,0 @@
/*
* UFC-crypt: ultra fast crypt(3) implementation
*
* Copyright (C) 1991-2023 Free Software Foundation, Inc.
*
* The GNU C Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* The GNU C Library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the GNU C Library; if not, see
* <https://www.gnu.org/licenses/>.
*
* @(#)crypt-private.h 1.4 12/20/96
*/
/* Prototypes for local functions in libcrypt.a. */
#ifndef CRYPT_PRIVATE_H
#define CRYPT_PRIVATE_H 1
#include <features.h>
#include <stdbool.h>
#ifndef DOS
#include "ufc-crypt.h"
#else
/*
* Thanks to greg%wind@plains.NoDak.edu (Greg W. Wettstein)
* for DOS patches
*/
#include "pl.h"
#include "ufc.h"
#endif
#include "crypt.h"
/* crypt.c */
extern void _ufc_doit_r (ufc_long itr, struct crypt_data * __restrict __data,
ufc_long *res);
/* crypt_util.c */
extern void __init_des_r (struct crypt_data * __restrict __data);
extern void __init_des (void);
extern bool _ufc_setup_salt_r (const char *s,
struct crypt_data * __restrict __data);
extern void _ufc_mk_keytab_r (const char *key,
struct crypt_data * __restrict __data);
extern void _ufc_dofinalperm_r (ufc_long *res,
struct crypt_data * __restrict __data);
extern void _ufc_output_conversion_r (ufc_long v1, ufc_long v2,
const char *salt,
struct crypt_data * __restrict __data);
extern void __setkey_r (const char *__key,
struct crypt_data * __restrict __data);
extern void __encrypt_r (char * __restrict __block, int __edflag,
struct crypt_data * __restrict __data);
/* crypt-entry.c */
extern char *__crypt_r (const char *__key, const char *__salt,
struct crypt_data * __restrict __data);
extern char *fcrypt (const char *key, const char *salt);
extern void __b64_from_24bit (char **cp, int *buflen,
unsigned int b2, unsigned int b1, unsigned int b0,
int n);
#endif /* crypt-private.h */

View File

@ -1,115 +0,0 @@
/*
* UFC-crypt: ultra fast crypt(3) implementation
*
* Copyright (C) 1991-2023 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see the file COPYING.LIB. If not,
* see <https://www.gnu.org/licenses/>.
*
* @(#)crypt.c 2.25 12/20/96
*
* Semiportable C version
*
*/
#include "crypt-private.h"
#ifdef _UFC_32_
/*
* 32 bit version
*/
#define SBA(sb, v) (*(long32*)((char*)(sb)+(v)))
void
_ufc_doit_r (ufc_long itr, struct crypt_data * __restrict __data,
ufc_long *res)
{
int i;
long32 s, *k;
long32 *sb01 = (long32*)__data->sb0;
long32 *sb23 = (long32*)__data->sb2;
long32 l1, l2, r1, r2;
l1 = (long32)res[0]; l2 = (long32)res[1];
r1 = (long32)res[2]; r2 = (long32)res[3];
while(itr--) {
k = (long32*)__data->keysched;
for(i=8; i--; ) {
s = *k++ ^ r1;
l1 ^= SBA(sb01, s & 0xffff); l2 ^= SBA(sb01, (s & 0xffff)+4);
l1 ^= SBA(sb01, s >>= 16 ); l2 ^= SBA(sb01, (s )+4);
s = *k++ ^ r2;
l1 ^= SBA(sb23, s & 0xffff); l2 ^= SBA(sb23, (s & 0xffff)+4);
l1 ^= SBA(sb23, s >>= 16 ); l2 ^= SBA(sb23, (s )+4);
s = *k++ ^ l1;
r1 ^= SBA(sb01, s & 0xffff); r2 ^= SBA(sb01, (s & 0xffff)+4);
r1 ^= SBA(sb01, s >>= 16 ); r2 ^= SBA(sb01, (s )+4);
s = *k++ ^ l2;
r1 ^= SBA(sb23, s & 0xffff); r2 ^= SBA(sb23, (s & 0xffff)+4);
r1 ^= SBA(sb23, s >>= 16 ); r2 ^= SBA(sb23, (s )+4);
}
s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s;
}
res[0] = l1; res[1] = l2; res[2] = r1; res[3] = r2;
}
#endif
#ifdef _UFC_64_
/*
* 64 bit version
*/
#define SBA(sb, v) (*(long64*)((char*)(sb)+(v)))
void
_ufc_doit_r (ufc_long itr, struct crypt_data * __restrict __data,
ufc_long *res)
{
int i;
long64 l, r, s, *k;
long64 *sb01 = (long64*)__data->sb0;
long64 *sb23 = (long64*)__data->sb2;
l = (((long64)res[0]) << 32) | ((long64)res[1]);
r = (((long64)res[2]) << 32) | ((long64)res[3]);
while(itr--) {
k = (long64*)__data->keysched;
for(i=8; i--; ) {
s = *k++ ^ r;
l ^= SBA(sb23, (s ) & 0xffff);
l ^= SBA(sb23, (s >>= 16) & 0xffff);
l ^= SBA(sb01, (s >>= 16) & 0xffff);
l ^= SBA(sb01, (s >>= 16) );
s = *k++ ^ l;
r ^= SBA(sb23, (s ) & 0xffff);
r ^= SBA(sb23, (s >>= 16) & 0xffff);
r ^= SBA(sb01, (s >>= 16) & 0xffff);
r ^= SBA(sb01, (s >>= 16) );
}
s=l; l=r; r=s;
}
res[0] = l >> 32; res[1] = l & 0xffffffff;
res[2] = r >> 32; res[3] = r & 0xffffffff;
}
#endif

View File

@ -1,70 +0,0 @@
/*
* UFC-crypt: ultra fast crypt(3) implementation
*
* Copyright (C) 1991-2023 Free Software Foundation, Inc.
*
* The GNU C Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* The GNU C Library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the GNU C Library; if not, see
* <https://www.gnu.org/licenses/>.
*
* @(#)crypt.h 1.5 12/20/96
*
*/
#ifndef _CRYPT_H
#define _CRYPT_H 1
#include <features.h>
__BEGIN_DECLS
/* One-way hash PHRASE, returning a string suitable for storage in the
user database. SALT selects the one-way function to use, and
ensures that no two users' hashes are the same, even if they use
the same passphrase. The return value points to static storage
which will be overwritten by the next call to crypt. */
extern char *crypt (const char *__phrase, const char *__salt)
__THROW __nonnull ((1, 2));
#ifdef __USE_GNU
/* This structure provides scratch and output buffers for 'crypt_r'.
Its contents should not be accessed directly. */
struct crypt_data
{
char keysched[16 * 8];
char sb0[32768];
char sb1[32768];
char sb2[32768];
char sb3[32768];
/* end-of-aligment-critical-data */
char crypt_3_buf[14];
char current_salt[2];
long int current_saltbits;
int direction, initialized;
};
/* Thread-safe version of 'crypt'.
DATA must point to a 'struct crypt_data' allocated by the caller.
Before the first call to 'crypt_r' with a new 'struct crypt_data',
that object must be initialized to all zeroes. The pointer
returned, if not NULL, will point within DATA. (It will still be
overwritten by the next call to 'crypt_r' with the same DATA.) */
extern char *crypt_r (const char *__phrase, const char *__salt,
struct crypt_data * __restrict __data)
__THROW __nonnull ((1, 2, 3));
#endif
__END_DECLS
#endif /* crypt.h */

View File

@ -1,946 +0,0 @@
/*
* UFC-crypt: ultra fast crypt(3) implementation
*
* Copyright (C) 1991-2023 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see the file COPYING.LIB. If not,
* see <https://www.gnu.org/licenses/>.
*
* @(#)crypt_util.c 2.56 12/20/96
*
* Support routines
*
*/
#ifdef DEBUG
#include <stdio.h>
#endif
#include <atomic.h>
#include <string.h>
#ifndef STATIC
#define STATIC static
#endif
#include "crypt-private.h"
#include <shlib-compat.h>
/* Prototypes for local functions. */
#ifndef __GNU_LIBRARY__
void _ufc_clearmem (char *start, int cnt);
void _ufc_copymem (char *from, char *to, int cnt);
#endif
#ifdef _UFC_32_
STATIC void shuffle_sb (long32 *k, ufc_long saltbits);
#else
STATIC void shuffle_sb (long64 *k, ufc_long saltbits);
#endif
/*
* Permutation done once on the 56 bit
* key derived from the original 8 byte ASCII key.
*/
static const int pc1[56] = {
57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
};
/*
* How much to rotate each 28 bit half of the pc1 permutated
* 56 bit key before using pc2 to give the i' key
*/
static const int rots[16] = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
/*
* Permutation giving the key
* of the i' DES round
*/
static const int pc2[48] = {
14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
};
/*
* The E expansion table which selects
* bits from the 32 bit intermediate result.
*/
static const int esel[48] = {
32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1
};
/*
* Permutation done on the
* result of sbox lookups
*/
static const int perm32[32] = {
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
};
/*
* The sboxes
*/
static const int sbox[8][4][16]= {
{ { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
{ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
{ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
{ 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
},
{ { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
{ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
{ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
{ 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
},
{ { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
{ 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
{ 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
{ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
},
{ { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
{ 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
{ 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
{ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
},
{ { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
{ 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
{ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
{ 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }
},
{ { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
{ 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
{ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
{ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }
},
{ { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
{ 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
{ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
{ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }
},
{ { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
{ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
{ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
{ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }
}
};
#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
/*
* This is the initial
* permutation matrix
*/
static const int initial_perm[64] = {
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
};
#endif
/*
* This is the final
* permutation matrix
*/
static const int final_perm[64] = {
40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
};
#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
static const ufc_long BITMASK[24] = {
0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000,
0x01000000, 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000,
0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200,
0x00000100, 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008
};
static const unsigned char bytemask[8] = {
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
};
static const ufc_long longmask[32] = {
0x80000000, 0x40000000, 0x20000000, 0x10000000,
0x08000000, 0x04000000, 0x02000000, 0x01000000,
0x00800000, 0x00400000, 0x00200000, 0x00100000,
0x00080000, 0x00040000, 0x00020000, 0x00010000,
0x00008000, 0x00004000, 0x00002000, 0x00001000,
0x00000800, 0x00000400, 0x00000200, 0x00000100,
0x00000080, 0x00000040, 0x00000020, 0x00000010,
0x00000008, 0x00000004, 0x00000002, 0x00000001
};
/*
* do_pc1: permform pc1 permutation in the key schedule generation.
*
* The first index is the byte number in the 8 byte ASCII key
* - second - - the two 28 bits halves of the result
* - third - selects the 7 bits actually used of each byte
*
* The result is kept with 28 bit per 32 bit with the 4 most significant
* bits zero.
*/
static ufc_long do_pc1[8][2][128];
/*
* do_pc2: permform pc2 permutation in the key schedule generation.
*
* The first index is the septet number in the two 28 bit intermediate values
* - second - - - septet values
*
* Knowledge of the structure of the pc2 permutation is used.
*
* The result is kept with 28 bit per 32 bit with the 4 most significant
* bits zero.
*/
static ufc_long do_pc2[8][128];
/*
* eperm32tab: do 32 bit permutation and E selection
*
* The first index is the byte number in the 32 bit value to be permuted
* - second - is the value of this byte
* - third - selects the two 32 bit values
*
* The table is used and generated internally in init_des to speed it up
*/
static ufc_long eperm32tab[4][256][2];
/*
* efp: undo an extra e selection and do final
* permutation giving the DES result.
*
* Invoked 6 bit a time on two 48 bit values
* giving two 32 bit longs.
*/
static ufc_long efp[16][64][2];
/* Table with characters for base64 transformation. */
static const char b64t[64] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
/*
* For use by the old, non-reentrant routines
* (crypt/encrypt/setkey)
*/
struct crypt_data _ufc_foobar;
#ifdef __GNU_LIBRARY__
#include <libc-lock.h>
__libc_lock_define_initialized (static, _ufc_tables_lock)
#endif
#ifdef DEBUG
void
_ufc_prbits (ufc_long *a, int n)
{
ufc_long i, j, t, tmp;
n /= 8;
for(i = 0; i < n; i++) {
tmp=0;
for(j = 0; j < 8; j++) {
t=8*i+j;
tmp|=(a[t/24] & BITMASK[t % 24])?bytemask[j]:0;
}
(void)printf("%02lx ", tmp);
}
printf(" ");
}
static void __attribute__ ((unused))
_ufc_set_bits (ufc_long v, ufc_long *b)
{
ufc_long i;
*b = 0;
for(i = 0; i < 24; i++) {
if(v & longmask[8 + i])
*b |= BITMASK[i];
}
}
#endif
#ifndef __GNU_LIBRARY__
/*
* Silly rewrites of 'bzero'/'memset'. I do so
* because some machines don't have
* bzero and some don't have memset.
*/
void
_ufc_clearmem (char *start, int cnt)
{
while(cnt--)
*start++ = '\0';
}
void
_ufc_copymem (char *from, char *to, int cnt)
{
while(cnt--)
*to++ = *from++;
}
#else
#define _ufc_clearmem(start, cnt) memset(start, 0, cnt)
#define _ufc_copymem(from, to, cnt) memcpy(to, from, cnt)
#endif
/* lookup a 6 bit value in sbox */
#define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf];
/*
* Initialize unit - may be invoked directly
* by fcrypt users.
*/
void
__init_des_r (struct crypt_data * __restrict __data)
{
int comes_from_bit;
int bit, sg;
ufc_long j;
ufc_long mask1, mask2;
int e_inverse[64];
static volatile int small_tables_initialized = 0;
#ifdef _UFC_32_
long32 *sb[4];
sb[0] = (long32*)__data->sb0; sb[1] = (long32*)__data->sb1;
sb[2] = (long32*)__data->sb2; sb[3] = (long32*)__data->sb3;
#endif
#ifdef _UFC_64_
long64 *sb[4];
sb[0] = (long64*)__data->sb0; sb[1] = (long64*)__data->sb1;
sb[2] = (long64*)__data->sb2; sb[3] = (long64*)__data->sb3;
#endif
if(small_tables_initialized == 0) {
#ifdef __GNU_LIBRARY__
__libc_lock_lock (_ufc_tables_lock);
if(small_tables_initialized)
goto small_tables_done;
#endif
/*
* Create the do_pc1 table used
* to affect pc1 permutation
* when generating keys
*/
_ufc_clearmem((char*)do_pc1, (int)sizeof(do_pc1));
for(bit = 0; bit < 56; bit++) {
comes_from_bit = pc1[bit] - 1;
mask1 = bytemask[comes_from_bit % 8 + 1];
mask2 = longmask[bit % 28 + 4];
for(j = 0; j < 128; j++) {
if(j & mask1)
do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2;
}
}
/*
* Create the do_pc2 table used
* to affect pc2 permutation when
* generating keys
*/
_ufc_clearmem((char*)do_pc2, (int)sizeof(do_pc2));
for(bit = 0; bit < 48; bit++) {
comes_from_bit = pc2[bit] - 1;
mask1 = bytemask[comes_from_bit % 7 + 1];
mask2 = BITMASK[bit % 24];
for(j = 0; j < 128; j++) {
if(j & mask1)
do_pc2[comes_from_bit / 7][j] |= mask2;
}
}
/*
* Now generate the table used to do combined
* 32 bit permutation and e expansion
*
* We use it because we have to permute 16384 32 bit
* longs into 48 bit in order to initialize sb.
*
* Looping 48 rounds per permutation becomes
* just too slow...
*
*/
_ufc_clearmem((char*)eperm32tab, (int)sizeof(eperm32tab));
for(bit = 0; bit < 48; bit++) {
ufc_long mask1,comes_from;
comes_from = perm32[esel[bit]-1]-1;
mask1 = bytemask[comes_from % 8];
for(j = 256; j--;) {
if(j & mask1)
eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK[bit % 24];
}
}
/*
* Create an inverse matrix for esel telling
* where to plug out bits if undoing it
*/
for(bit=48; bit--;) {
e_inverse[esel[bit] - 1 ] = bit;
e_inverse[esel[bit] - 1 + 32] = bit + 48;
}
/*
* create efp: the matrix used to
* undo the E expansion and effect final permutation
*/
_ufc_clearmem((char*)efp, (int)sizeof efp);
for(bit = 0; bit < 64; bit++) {
int o_bit, o_long;
ufc_long word_value, mask1, mask2;
int comes_from_f_bit, comes_from_e_bit;
int comes_from_word, bit_within_word;
/* See where bit i belongs in the two 32 bit long's */
o_long = bit / 32; /* 0..1 */
o_bit = bit % 32; /* 0..31 */
/*
* And find a bit in the e permutated value setting this bit.
*
* Note: the e selection may have selected the same bit several
* times. By the initialization of e_inverse, we only look
* for one specific instance.
*/
comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */
comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */
comes_from_word = comes_from_e_bit / 6; /* 0..15 */
bit_within_word = comes_from_e_bit % 6; /* 0..5 */
mask1 = longmask[bit_within_word + 26];
mask2 = longmask[o_bit];
for(word_value = 64; word_value--;) {
if(word_value & mask1)
efp[comes_from_word][word_value][o_long] |= mask2;
}
}
atomic_write_barrier ();
small_tables_initialized = 1;
#ifdef __GNU_LIBRARY__
small_tables_done:
__libc_lock_unlock(_ufc_tables_lock);
#endif
} else
atomic_read_barrier ();
/*
* Create the sb tables:
*
* For each 12 bit segment of an 48 bit intermediate
* result, the sb table precomputes the two 4 bit
* values of the sbox lookups done with the two 6
* bit halves, shifts them to their proper place,
* sends them through perm32 and finally E expands
* them so that they are ready for the next
* DES round.
*
*/
if (__data->sb0 + sizeof (__data->sb0) == __data->sb1
&& __data->sb1 + sizeof (__data->sb1) == __data->sb2
&& __data->sb2 + sizeof (__data->sb2) == __data->sb3)
_ufc_clearmem(__data->sb0,
(int)sizeof(__data->sb0)
+ (int)sizeof(__data->sb1)
+ (int)sizeof(__data->sb2)
+ (int)sizeof(__data->sb3));
else {
_ufc_clearmem(__data->sb0, (int)sizeof(__data->sb0));
_ufc_clearmem(__data->sb1, (int)sizeof(__data->sb1));
_ufc_clearmem(__data->sb2, (int)sizeof(__data->sb2));
_ufc_clearmem(__data->sb3, (int)sizeof(__data->sb3));
}
for(sg = 0; sg < 4; sg++) {
int j1, j2;
int s1, s2;
for(j1 = 0; j1 < 64; j1++) {
s1 = s_lookup(2 * sg, j1);
for(j2 = 0; j2 < 64; j2++) {
ufc_long to_permute, inx;
s2 = s_lookup(2 * sg + 1, j2);
to_permute = (((ufc_long)s1 << 4) |
(ufc_long)s2) << (24 - 8 * (ufc_long)sg);
#ifdef _UFC_32_
inx = ((j1 << 6) | j2) << 1;
sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0];
sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1];
sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0];
sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1];
sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0];
sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1];
sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0];
sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1];
#endif
#ifdef _UFC_64_
inx = ((j1 << 6) | j2);
sb[sg][inx] =
((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) |
(long64)eperm32tab[0][(to_permute >> 24) & 0xff][1];
sb[sg][inx] |=
((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) |
(long64)eperm32tab[1][(to_permute >> 16) & 0xff][1];
sb[sg][inx] |=
((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) |
(long64)eperm32tab[2][(to_permute >> 8) & 0xff][1];
sb[sg][inx] |=
((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) |
(long64)eperm32tab[3][(to_permute) & 0xff][1];
#endif
}
}
}
__data->current_saltbits = 0;
__data->current_salt[0] = 0;
__data->current_salt[1] = 0;
__data->initialized++;
}
void
__init_des (void)
{
__init_des_r(&_ufc_foobar);
}
/*
* Process the elements of the sb table permuting the
* bits swapped in the expansion by the current salt.
*/
#ifdef _UFC_32_
STATIC void
shuffle_sb (long32 *k, ufc_long saltbits)
{
ufc_long j;
long32 x;
for(j=4096; j--;) {
x = (k[0] ^ k[1]) & (long32)saltbits;
*k++ ^= x;
*k++ ^= x;
}
}
#endif
#ifdef _UFC_64_
STATIC void
shuffle_sb (long64 *k, ufc_long saltbits)
{
ufc_long j;
long64 x;
for(j=4096; j--;) {
x = ((*k >> 32) ^ *k) & (long64)saltbits;
*k++ ^= (x << 32) | x;
}
}
#endif
/*
* Return false iff C is in the specified alphabet for crypt salt.
*/
static bool
bad_for_salt (char c)
{
switch (c)
{
case '0' ... '9':
case 'A' ... 'Z':
case 'a' ... 'z':
case '.': case '/':
return false;
default:
return true;
}
}
/*
* Setup the unit for a new salt
* Hopefully we'll not see a new salt in each crypt call.
* Return false if an unexpected character was found in s[0] or s[1].
*/
bool
_ufc_setup_salt_r (const char *s, struct crypt_data * __restrict __data)
{
ufc_long i, j, saltbits;
char s0, s1;
if(__data->initialized == 0)
__init_des_r(__data);
s0 = s[0];
if(bad_for_salt (s0))
return false;
s1 = s[1];
if(bad_for_salt (s1))
return false;
if(s0 == __data->current_salt[0] && s1 == __data->current_salt[1])
return true;
__data->current_salt[0] = s0;
__data->current_salt[1] = s1;
/*
* This is the only crypt change to DES:
* entries are swapped in the expansion table
* according to the bits set in the salt.
*/
saltbits = 0;
for(i = 0; i < 2; i++) {
long c=ascii_to_bin(s[i]);
for(j = 0; j < 6; j++) {
if((c >> j) & 0x1)
saltbits |= BITMASK[6 * i + j];
}
}
/*
* Permute the sb table values
* to reflect the changed e
* selection table
*/
#ifdef _UFC_32_
#define LONGG long32*
#endif
#ifdef _UFC_64_
#define LONGG long64*
#endif
shuffle_sb((LONGG)__data->sb0, __data->current_saltbits ^ saltbits);
shuffle_sb((LONGG)__data->sb1, __data->current_saltbits ^ saltbits);
shuffle_sb((LONGG)__data->sb2, __data->current_saltbits ^ saltbits);
shuffle_sb((LONGG)__data->sb3, __data->current_saltbits ^ saltbits);
__data->current_saltbits = saltbits;
return true;
}
void
_ufc_mk_keytab_r (const char *key, struct crypt_data * __restrict __data)
{
ufc_long v1, v2, *k1;
int i;
#ifdef _UFC_32_
long32 v, *k2;
k2 = (long32*)__data->keysched;
#endif
#ifdef _UFC_64_
long64 v, *k2;
k2 = (long64*)__data->keysched;
#endif
v1 = v2 = 0; k1 = &do_pc1[0][0][0];
for(i = 8; i--;) {
v1 |= k1[*key & 0x7f]; k1 += 128;
v2 |= k1[*key++ & 0x7f]; k1 += 128;
}
for(i = 0; i < 16; i++) {
k1 = &do_pc2[0][0];
v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i]));
v = k1[(v1 >> 21) & 0x7f]; k1 += 128;
v |= k1[(v1 >> 14) & 0x7f]; k1 += 128;
v |= k1[(v1 >> 7) & 0x7f]; k1 += 128;
v |= k1[(v1 ) & 0x7f]; k1 += 128;
#ifdef _UFC_32_
*k2++ = (v | 0x00008000);
v = 0;
#endif
#ifdef _UFC_64_
v = (v << 32);
#endif
v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i]));
v |= k1[(v2 >> 21) & 0x7f]; k1 += 128;
v |= k1[(v2 >> 14) & 0x7f]; k1 += 128;
v |= k1[(v2 >> 7) & 0x7f]; k1 += 128;
v |= k1[(v2 ) & 0x7f];
#ifdef _UFC_32_
*k2++ = (v | 0x00008000);
#endif
#ifdef _UFC_64_
*k2++ = v | 0x0000800000008000l;
#endif
}
__data->direction = 0;
}
/*
* Undo an extra E selection and do final permutations
*/
void
_ufc_dofinalperm_r (ufc_long *res, struct crypt_data * __restrict __data)
{
ufc_long v1, v2, x;
ufc_long l1,l2,r1,r2;
l1 = res[0]; l2 = res[1];
r1 = res[2]; r2 = res[3];
x = (l1 ^ l2) & __data->current_saltbits; l1 ^= x; l2 ^= x;
x = (r1 ^ r2) & __data->current_saltbits; r1 ^= x; r2 ^= x;
v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3;
v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1];
v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1];
v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1];
v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1];
v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1];
v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1];
v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1];
v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1];
v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1];
v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1];
v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1];
v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1];
v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1];
v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1];
v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1];
v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1];
res[0] = v1; res[1] = v2;
}
/*
* crypt only: convert from 64 bit to 11 bit ASCII
* prefixing with the salt
*/
void
_ufc_output_conversion_r (ufc_long v1, ufc_long v2, const char *salt,
struct crypt_data * __restrict __data)
{
int i, s, shf;
__data->crypt_3_buf[0] = salt[0];
__data->crypt_3_buf[1] = salt[1] ? salt[1] : salt[0];
for(i = 0; i < 5; i++) {
shf = (26 - 6 * i); /* to cope with MSC compiler bug */
__data->crypt_3_buf[i + 2] = bin_to_ascii((v1 >> shf) & 0x3f);
}
s = (v2 & 0xf) << 2;
v2 = (v2 >> 2) | ((v1 & 0x3) << 30);
for(i = 5; i < 10; i++) {
shf = (56 - 6 * i);
__data->crypt_3_buf[i + 2] = bin_to_ascii((v2 >> shf) & 0x3f);
}
__data->crypt_3_buf[12] = bin_to_ascii(s);
__data->crypt_3_buf[13] = 0;
}
#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
/*
* UNIX encrypt function. Takes a bitvector
* represented by one byte per bit and
* encrypt/decrypt according to edflag
*/
void
__encrypt_r (char *__block, int __edflag,
struct crypt_data * __restrict __data)
{
ufc_long l1, l2, r1, r2, res[4];
int i;
#ifdef _UFC_32_
long32 *kt;
kt = (long32*)__data->keysched;
#endif
#ifdef _UFC_64_
long64 *kt;
kt = (long64*)__data->keysched;
#endif
/*
* Undo any salt changes to E expansion
*/
_ufc_setup_salt_r("..", __data);
/*
* Reverse key table if
* changing operation (encrypt/decrypt)
*/
if((__edflag == 0) != (__data->direction == 0)) {
for(i = 0; i < 8; i++) {
#ifdef _UFC_32_
long32 x;
x = kt[2 * (15-i)];
kt[2 * (15-i)] = kt[2 * i];
kt[2 * i] = x;
x = kt[2 * (15-i) + 1];
kt[2 * (15-i) + 1] = kt[2 * i + 1];
kt[2 * i + 1] = x;
#endif
#ifdef _UFC_64_
long64 x;
x = kt[15-i];
kt[15-i] = kt[i];
kt[i] = x;
#endif
}
__data->direction = __edflag;
}
/*
* Do initial permutation + E expansion
*/
i = 0;
for(l1 = 0; i < 24; i++) {
if(__block[initial_perm[esel[i]-1]-1])
l1 |= BITMASK[i];
}
for(l2 = 0; i < 48; i++) {
if(__block[initial_perm[esel[i]-1]-1])
l2 |= BITMASK[i-24];
}
i = 0;
for(r1 = 0; i < 24; i++) {
if(__block[initial_perm[esel[i]-1+32]-1])
r1 |= BITMASK[i];
}
for(r2 = 0; i < 48; i++) {
if(__block[initial_perm[esel[i]-1+32]-1])
r2 |= BITMASK[i-24];
}
/*
* Do DES inner loops + final conversion
*/
res[0] = l1; res[1] = l2;
res[2] = r1; res[3] = r2;
_ufc_doit_r((ufc_long)1, __data, &res[0]);
/*
* Do final permutations
*/
_ufc_dofinalperm_r(res, __data);
/*
* And convert to bit array
*/
l1 = res[0]; r1 = res[1];
for(i = 0; i < 32; i++) {
*__block++ = (l1 & longmask[i]) != 0;
}
for(i = 0; i < 32; i++) {
*__block++ = (r1 & longmask[i]) != 0;
}
}
weak_alias (__encrypt_r, encrypt_r)
compat_symbol (libcrypt, encrypt_r, encrypt_r, GLIBC_2_0);
void
encrypt (char *__block, int __edflag)
{
__encrypt_r(__block, __edflag, &_ufc_foobar);
}
compat_symbol (libcrypt, encrypt, encrypt, GLIBC_2_0);
/*
* UNIX setkey function. Take a 64 bit DES
* key and setup the machinery.
*/
void
__setkey_r (const char *__key, struct crypt_data * __restrict __data)
{
int i,j;
unsigned char c;
unsigned char ktab[8];
_ufc_setup_salt_r("..", __data); /* be sure we're initialized */
for(i = 0; i < 8; i++) {
for(j = 0, c = 0; j < 8; j++)
c = c << 1 | *__key++;
ktab[i] = c >> 1;
}
_ufc_mk_keytab_r((char *) ktab, __data);
}
weak_alias (__setkey_r, setkey_r)
compat_symbol (libcrypt, setkey_r, setkey_r, GLIBC_2_0);
void
setkey (const char *__key)
{
__setkey_r(__key, &_ufc_foobar);
}
compat_symbol (libcrypt, setkey, setkey, GLIBC_2_0);
#endif /* SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28) */
void
__b64_from_24bit (char **cp, int *buflen,
unsigned int b2, unsigned int b1, unsigned int b0,
int n)
{
unsigned int w = (b2 << 16) | (b1 << 8) | b0;
while (n-- > 0 && (*buflen) > 0)
{
*(*cp)++ = b64t[w & 0x3f];
--(*buflen);
w >>= 6;
}
}

View File

@ -1,331 +0,0 @@
/* One way encryption based on MD5 sum.
Compatible with the behavior of MD5 crypt introduced in FreeBSD 2.0.
Copyright (C) 1996-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include "md5.h"
#include "crypt-private.h"
#ifdef USE_NSS
typedef int PRBool;
# include <hasht.h>
# include <nsslowhash.h>
# define md5_init_ctx(ctxp, nss_ctxp) \
do \
{ \
if (((nss_ctxp = NSSLOWHASH_NewContext (nss_ictx, HASH_AlgMD5)) \
== NULL)) \
{ \
if (nss_ctx != NULL) \
NSSLOWHASH_Destroy (nss_ctx); \
if (nss_alt_ctx != NULL) \
NSSLOWHASH_Destroy (nss_alt_ctx); \
return NULL; \
} \
NSSLOWHASH_Begin (nss_ctxp); \
} \
while (0)
# define md5_process_bytes(buf, len, ctxp, nss_ctxp) \
NSSLOWHASH_Update (nss_ctxp, (const unsigned char *) buf, len)
# define md5_finish_ctx(ctxp, nss_ctxp, result) \
do \
{ \
unsigned int ret; \
NSSLOWHASH_End (nss_ctxp, result, &ret, sizeof (result)); \
assert (ret == sizeof (result)); \
NSSLOWHASH_Destroy (nss_ctxp); \
nss_ctxp = NULL; \
} \
while (0)
#else
# define md5_init_ctx(ctxp, nss_ctxp) \
__md5_init_ctx (ctxp)
# define md5_process_bytes(buf, len, ctxp, nss_ctxp) \
__md5_process_bytes(buf, len, ctxp)
# define md5_finish_ctx(ctxp, nss_ctxp, result) \
__md5_finish_ctx (ctxp, result)
#endif
/* Define our magic string to mark salt for MD5 "encryption"
replacement. This is meant to be the same as for other MD5 based
encryption implementations. */
static const char md5_salt_prefix[] = "$1$";
/* Prototypes for local functions. */
extern char *__md5_crypt_r (const char *key, const char *salt,
char *buffer, int buflen);
extern char *__md5_crypt (const char *key, const char *salt);
/* This entry point is equivalent to the `crypt' function in Unix
libcs. */
char *
__md5_crypt_r (const char *key, const char *salt, char *buffer, int buflen)
{
unsigned char alt_result[16]
__attribute__ ((__aligned__ (__alignof__ (md5_uint32))));
size_t salt_len;
size_t key_len;
size_t cnt;
char *cp;
char *copied_key = NULL;
char *copied_salt = NULL;
char *free_key = NULL;
size_t alloca_used = 0;
/* Find beginning of salt string. The prefix should normally always
be present. Just in case it is not. */
if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
/* Skip salt prefix. */
salt += sizeof (md5_salt_prefix) - 1;
salt_len = MIN (strcspn (salt, "$"), 8);
key_len = strlen (key);
if (((uintptr_t) key) % __alignof__ (md5_uint32) != 0)
{
char *tmp;
if (__libc_use_alloca (alloca_used + key_len + __alignof__ (md5_uint32)))
tmp = (char *) alloca (key_len + __alignof__ (md5_uint32));
else
{
free_key = tmp = (char *) malloc (key_len + __alignof__ (md5_uint32));
if (tmp == NULL)
return NULL;
}
key = copied_key =
memcpy (tmp + __alignof__ (md5_uint32)
- ((uintptr_t) tmp) % __alignof__ (md5_uint32),
key, key_len);
assert (((uintptr_t) key) % __alignof__ (md5_uint32) == 0);
}
if (((uintptr_t) salt) % __alignof__ (md5_uint32) != 0)
{
char *tmp = (char *) alloca (salt_len + __alignof__ (md5_uint32));
salt = copied_salt =
memcpy (tmp + __alignof__ (md5_uint32)
- ((uintptr_t) tmp) % __alignof__ (md5_uint32),
salt, salt_len);
assert (((uintptr_t) salt) % __alignof__ (md5_uint32) == 0);
}
#ifdef USE_NSS
/* Initialize libfreebl3. */
NSSLOWInitContext *nss_ictx = NSSLOW_Init ();
if (nss_ictx == NULL)
{
free (free_key);
return NULL;
}
NSSLOWHASHContext *nss_ctx = NULL;
NSSLOWHASHContext *nss_alt_ctx = NULL;
#else
struct md5_ctx ctx;
struct md5_ctx alt_ctx;
#endif
/* Prepare for the real work. */
md5_init_ctx (&ctx, nss_ctx);
/* Add the key string. */
md5_process_bytes (key, key_len, &ctx, nss_ctx);
/* Because the SALT argument need not always have the salt prefix we
add it separately. */
md5_process_bytes (md5_salt_prefix, sizeof (md5_salt_prefix) - 1,
&ctx, nss_ctx);
/* The last part is the salt string. This must be at most 8
characters and it ends at the first `$' character (for
compatibility with existing implementations). */
md5_process_bytes (salt, salt_len, &ctx, nss_ctx);
/* Compute alternate MD5 sum with input KEY, SALT, and KEY. The
final result will be added to the first context. */
md5_init_ctx (&alt_ctx, nss_alt_ctx);
/* Add key. */
md5_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Add salt. */
md5_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
/* Add key again. */
md5_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Now get result of this (16 bytes) and add it to the other
context. */
md5_finish_ctx (&alt_ctx, nss_alt_ctx, alt_result);
/* Add for any character in the key one byte of the alternate sum. */
for (cnt = key_len; cnt > 16; cnt -= 16)
md5_process_bytes (alt_result, 16, &ctx, nss_ctx);
md5_process_bytes (alt_result, cnt, &ctx, nss_ctx);
/* For the following code we need a NUL byte. */
*alt_result = '\0';
/* The original implementation now does something weird: for every 1
bit in the key the first 0 is added to the buffer, for every 0
bit the first character of the key. This does not seem to be
what was intended but we have to follow this to be compatible. */
for (cnt = key_len; cnt > 0; cnt >>= 1)
md5_process_bytes ((cnt & 1) != 0
? (const void *) alt_result : (const void *) key, 1,
&ctx, nss_ctx);
/* Create intermediate result. */
md5_finish_ctx (&ctx, nss_ctx, alt_result);
/* Now comes another weirdness. In fear of password crackers here
comes a quite long loop which just processes the output of the
previous round again. We cannot ignore this here. */
for (cnt = 0; cnt < 1000; ++cnt)
{
/* New context. */
md5_init_ctx (&ctx, nss_ctx);
/* Add key or last result. */
if ((cnt & 1) != 0)
md5_process_bytes (key, key_len, &ctx, nss_ctx);
else
md5_process_bytes (alt_result, 16, &ctx, nss_ctx);
/* Add salt for numbers not divisible by 3. */
if (cnt % 3 != 0)
md5_process_bytes (salt, salt_len, &ctx, nss_ctx);
/* Add key for numbers not divisible by 7. */
if (cnt % 7 != 0)
md5_process_bytes (key, key_len, &ctx, nss_ctx);
/* Add key or last result. */
if ((cnt & 1) != 0)
md5_process_bytes (alt_result, 16, &ctx, nss_ctx);
else
md5_process_bytes (key, key_len, &ctx, nss_ctx);
/* Create intermediate result. */
md5_finish_ctx (&ctx, nss_ctx, alt_result);
}
#ifdef USE_NSS
/* Free libfreebl3 resources. */
NSSLOW_Shutdown (nss_ictx);
#endif
/* Now we can construct the result string. It consists of three
parts. */
cp = __stpncpy (buffer, md5_salt_prefix, MAX (0, buflen));
buflen -= sizeof (md5_salt_prefix) - 1;
cp = __stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
if (buflen > 0)
{
*cp++ = '$';
--buflen;
}
__b64_from_24bit (&cp, &buflen,
alt_result[0], alt_result[6], alt_result[12], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[1], alt_result[7], alt_result[13], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[2], alt_result[8], alt_result[14], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[3], alt_result[9], alt_result[15], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[4], alt_result[10], alt_result[5], 4);
__b64_from_24bit (&cp, &buflen,
0, 0, alt_result[11], 2);
if (buflen <= 0)
{
__set_errno (ERANGE);
buffer = NULL;
}
else
*cp = '\0'; /* Terminate the string. */
/* Clear the buffer for the intermediate result so that people
attaching to processes or reading core dumps cannot get any
information. We do it in this way to clear correct_words[]
inside the MD5 implementation as well. */
#ifndef USE_NSS
__md5_init_ctx (&ctx);
__md5_finish_ctx (&ctx, alt_result);
explicit_bzero (&ctx, sizeof (ctx));
explicit_bzero (&alt_ctx, sizeof (alt_ctx));
#endif
if (copied_key != NULL)
explicit_bzero (copied_key, key_len);
if (copied_salt != NULL)
explicit_bzero (copied_salt, salt_len);
free (free_key);
return buffer;
}
static char *buffer;
char *
__md5_crypt (const char *key, const char *salt)
{
/* We don't want to have an arbitrary limit in the size of the
password. We can compute the size of the result in advance and
so we can prepare the buffer we pass to `md5_crypt_r'. */
static int buflen;
int needed = 3 + strlen (salt) + 1 + 26 + 1;
if (buflen < needed)
{
char *new_buffer = (char *) realloc (buffer, needed);
if (new_buffer == NULL)
return NULL;
buffer = new_buffer;
buflen = needed;
}
return __md5_crypt_r (key, salt, buffer, buflen);
}
static void
__attribute__ ((__destructor__))
free_mem (void)
{
free (buffer);
}

View File

@ -1,18 +0,0 @@
#include <crypt.h>
#include <string.h>
int
main (int argc, char *argv[])
{
const char salt[] = "$1$saltstring";
char *cp;
int result = 0;
cp = crypt ("Hello world!", salt);
/* MD5 is disabled in FIPS mode. */
if (cp)
result |= strcmp ("$1$saltstri$YMyguxXMBpd2TEZ.vS/3q1", cp);
return result;
}

View File

@ -1,137 +0,0 @@
/* Testcase for https://sourceware.org/bugzilla/show_bug.cgi?id=14090.
Copyright (C) 2012-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
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; 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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include "md5.h"
/* This test will not work with 32-bit size_t, so let it succeed
there. */
#if SIZE_MAX <= UINT32_MAX
static int
do_test (void)
{
return 0;
}
#else
# define CONST_2G 0x080000000
# define CONST_10G 0x280000000
/* MD5 sum values of zero-filled blocks of specified sizes. */
static const struct test_data_s
{
const char ref[16];
size_t len;
} test_data[] =
{
{ "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e",
0x000000000 },
{ "\xa9\x81\x13\x0c\xf2\xb7\xe0\x9f\x46\x86\xdc\x27\x3c\xf7\x18\x7e",
0x080000000 },
{ "\xc9\xa5\xa6\x87\x8d\x97\xb4\x8c\xc9\x65\xc1\xe4\x18\x59\xf0\x34",
0x100000000 },
{ "\x58\xcf\x63\x8a\x73\x3f\x91\x90\x07\xb4\x28\x7c\xf5\x39\x6d\x0c",
0x180000000 },
{ "\xb7\x70\x35\x1f\xad\xae\x5a\x96\xbb\xaf\x97\x02\xed\x97\xd2\x8d",
0x200000000 },
{ "\x2d\xd2\x6c\x4d\x47\x99\xeb\xd2\x9f\xa3\x1e\x48\xd4\x9e\x8e\x53",
0x280000000 },
};
static int
report (const char *id, const char *md5, size_t len, const char *ref)
{
if (memcmp (md5, ref, 16))
{
printf ("test %s with size %zd failed\n", id, len);
return 1;
}
return 0;
}
/* Test md5 in a single md5_process_bytes call. */
static int
test_single (void *buf, size_t len, const char *ref)
{
char sum[16];
struct md5_ctx ctx;
__md5_init_ctx (&ctx);
__md5_process_bytes (buf, len, &ctx);
__md5_finish_ctx (&ctx, sum);
return report ("single", sum, len, ref);
}
/* Test md5 with two md5_process_bytes calls to trigger a
different path in md5_process_block for sizes > 2 GB. */
static int
test_double (void *buf, size_t len, const char *ref)
{
char sum[16];
struct md5_ctx ctx;
__md5_init_ctx (&ctx);
if (len >= CONST_2G)
{
__md5_process_bytes (buf, CONST_2G, &ctx);
__md5_process_bytes (buf + CONST_2G, len - CONST_2G, &ctx);
}
else
__md5_process_bytes (buf, len, &ctx);
__md5_finish_ctx (&ctx, sum);
return report ("double", sum, len, ref);
}
static int
do_test (void)
{
void *buf;
unsigned int j;
int result = 0;
buf = mmap64 (0, CONST_10G, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (buf == MAP_FAILED)
{
puts ("Could not allocate 10 GB via mmap, skipping test.");
return 0;
}
for (j = 0; j < sizeof (test_data) / sizeof (struct test_data_s); j++)
{
if (test_single (buf, test_data[j].len, test_data[j].ref))
result = 1;
if (test_double (buf, test_data[j].len, test_data[j].ref))
result = 1;
}
return result;
}
#endif
/* This needs on a fast machine 90s. */
#define TIMEOUT 480
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -1,53 +0,0 @@
#include <string.h>
#include "md5.h"
static const struct
{
const char *input;
const char result[16];
} tests[] =
{
{ "",
"\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e" },
{ "a",
"\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8\x31\xc3\x99\xe2\x69\x77\x26\x61" },
{ "abc",
"\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f\x72" },
{ "message digest",
"\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61\xd0" },
{ "abcdefghijklmnopqrstuvwxyz",
"\xc3\xfc\xd3\xd7\x61\x92\xe4\x00\x7d\xfb\x49\x6c\xca\x67\xe1\x3b" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f" },
{ "123456789012345678901234567890123456789012345678901234567890"
"12345678901234567890",
"\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6\x7a" }
};
int
main (int argc, char *argv[])
{
struct md5_ctx ctx;
char sum[16];
int result = 0;
int cnt;
for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt)
{
int i;
__md5_init_ctx (&ctx);
__md5_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx);
__md5_finish_ctx (&ctx, sum);
result |= memcmp (tests[cnt].result, sum, 16);
__md5_init_ctx (&ctx);
for (i = 0; tests[cnt].input[i] != '\0'; ++i)
__md5_process_bytes (&tests[cnt].input[i], 1, &ctx);
__md5_finish_ctx (&ctx, sum);
result |= memcmp (tests[cnt].result, sum, 16);
}
return result;
}

View File

@ -1,98 +0,0 @@
#include <stdint.h>
/* Process LEN bytes of BUFFER, accumulating context into CTX.
It is assumed that LEN % 64 == 0. */
void
__sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx)
{
const uint32_t *words = buffer;
size_t nwords = len / sizeof (uint32_t);
uint32_t a = ctx->H[0];
uint32_t b = ctx->H[1];
uint32_t c = ctx->H[2];
uint32_t d = ctx->H[3];
uint32_t e = ctx->H[4];
uint32_t f = ctx->H[5];
uint32_t g = ctx->H[6];
uint32_t h = ctx->H[7];
/* First increment the byte count. FIPS 180-2 specifies the possible
length of the file up to 2^64 bits. Here we only compute the
number of bytes. */
ctx->total64 += len;
/* Process all bytes in the buffer with 64 bytes in each round of
the loop. */
while (nwords > 0)
{
uint32_t W[64];
uint32_t a_save = a;
uint32_t b_save = b;
uint32_t c_save = c;
uint32_t d_save = d;
uint32_t e_save = e;
uint32_t f_save = f;
uint32_t g_save = g;
uint32_t h_save = h;
/* Operators defined in FIPS 180-2:4.1.2. */
#define Ch(x, y, z) ((x & y) ^ (~x & z))
#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define S0(x) (CYCLIC (x, 2) ^ CYCLIC (x, 13) ^ CYCLIC (x, 22))
#define S1(x) (CYCLIC (x, 6) ^ CYCLIC (x, 11) ^ CYCLIC (x, 25))
#define R0(x) (CYCLIC (x, 7) ^ CYCLIC (x, 18) ^ (x >> 3))
#define R1(x) (CYCLIC (x, 17) ^ CYCLIC (x, 19) ^ (x >> 10))
/* It is unfortunate that C does not provide an operator for
cyclic rotation. Hope the C compiler is smart enough. */
#define CYCLIC(w, s) ((w >> s) | (w << (32 - s)))
/* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */
for (unsigned int t = 0; t < 16; ++t)
{
W[t] = SWAP (*words);
++words;
}
for (unsigned int t = 16; t < 64; ++t)
W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16];
/* The actual computation according to FIPS 180-2:6.2.2 step 3. */
for (unsigned int t = 0; t < 64; ++t)
{
uint32_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t];
uint32_t T2 = S0 (a) + Maj (a, b, c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
}
/* Add the starting values of the context according to FIPS 180-2:6.2.2
step 4. */
a += a_save;
b += b_save;
c += c_save;
d += d_save;
e += e_save;
f += f_save;
g += g_save;
h += h_save;
/* Prepare for the next round. */
nwords -= 16;
}
/* Put checksum in context given as argument. */
ctx->H[0] = a;
ctx->H[1] = b;
ctx->H[2] = c;
ctx->H[3] = d;
ctx->H[4] = e;
ctx->H[5] = f;
ctx->H[6] = g;
ctx->H[7] = h;
}

View File

@ -1,423 +0,0 @@
/* One way encryption based on SHA256 sum.
Copyright (C) 2007-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/param.h>
#include "sha256.h"
#include "crypt-private.h"
#ifdef USE_NSS
typedef int PRBool;
# include <hasht.h>
# include <nsslowhash.h>
# define sha256_init_ctx(ctxp, nss_ctxp) \
do \
{ \
if (((nss_ctxp = NSSLOWHASH_NewContext (nss_ictx, HASH_AlgSHA256)) \
== NULL)) \
{ \
if (nss_ctx != NULL) \
NSSLOWHASH_Destroy (nss_ctx); \
if (nss_alt_ctx != NULL) \
NSSLOWHASH_Destroy (nss_alt_ctx); \
return NULL; \
} \
NSSLOWHASH_Begin (nss_ctxp); \
} \
while (0)
# define sha256_process_bytes(buf, len, ctxp, nss_ctxp) \
NSSLOWHASH_Update (nss_ctxp, (const unsigned char *) buf, len)
# define sha256_finish_ctx(ctxp, nss_ctxp, result) \
do \
{ \
unsigned int ret; \
NSSLOWHASH_End (nss_ctxp, result, &ret, sizeof (result)); \
assert (ret == sizeof (result)); \
NSSLOWHASH_Destroy (nss_ctxp); \
nss_ctxp = NULL; \
} \
while (0)
#else
# define sha256_init_ctx(ctxp, nss_ctxp) \
__sha256_init_ctx (ctxp)
# define sha256_process_bytes(buf, len, ctxp, nss_ctxp) \
__sha256_process_bytes(buf, len, ctxp)
# define sha256_finish_ctx(ctxp, nss_ctxp, result) \
__sha256_finish_ctx (ctxp, result)
#endif
/* Define our magic string to mark salt for SHA256 "encryption"
replacement. */
static const char sha256_salt_prefix[] = "$5$";
/* Prefix for optional rounds specification. */
static const char sha256_rounds_prefix[] = "rounds=";
/* Maximum salt string length. */
#define SALT_LEN_MAX 16
/* Default number of rounds if not explicitly specified. */
#define ROUNDS_DEFAULT 5000
/* Minimum number of rounds. */
#define ROUNDS_MIN 1000
/* Maximum number of rounds. */
#define ROUNDS_MAX 999999999
/* Prototypes for local functions. */
extern char *__sha256_crypt_r (const char *key, const char *salt,
char *buffer, int buflen);
extern char *__sha256_crypt (const char *key, const char *salt);
char *
__sha256_crypt_r (const char *key, const char *salt, char *buffer, int buflen)
{
unsigned char alt_result[32]
__attribute__ ((__aligned__ (__alignof__ (uint32_t))));
unsigned char temp_result[32]
__attribute__ ((__aligned__ (__alignof__ (uint32_t))));
size_t salt_len;
size_t key_len;
size_t cnt;
char *cp;
char *copied_key = NULL;
char *copied_salt = NULL;
char *p_bytes;
char *s_bytes;
/* Default number of rounds. */
size_t rounds = ROUNDS_DEFAULT;
bool rounds_custom = false;
size_t alloca_used = 0;
char *free_key = NULL;
char *free_pbytes = NULL;
/* Find beginning of salt string. The prefix should normally always
be present. Just in case it is not. */
if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
/* Skip salt prefix. */
salt += sizeof (sha256_salt_prefix) - 1;
if (strncmp (salt, sha256_rounds_prefix, sizeof (sha256_rounds_prefix) - 1)
== 0)
{
const char *num = salt + sizeof (sha256_rounds_prefix) - 1;
char *endp;
unsigned long int srounds = strtoul (num, &endp, 10);
if (*endp == '$')
{
salt = endp + 1;
rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
rounds_custom = true;
}
}
salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
key_len = strlen (key);
if (((uintptr_t) key) % __alignof__ (uint32_t) != 0)
{
char *tmp;
if (__libc_use_alloca (alloca_used + key_len + __alignof__ (uint32_t)))
tmp = alloca_account (key_len + __alignof__ (uint32_t), alloca_used);
else
{
free_key = tmp = (char *) malloc (key_len + __alignof__ (uint32_t));
if (tmp == NULL)
return NULL;
}
key = copied_key =
memcpy (tmp + __alignof__ (uint32_t)
- ((uintptr_t) tmp) % __alignof__ (uint32_t),
key, key_len);
assert (((uintptr_t) key) % __alignof__ (uint32_t) == 0);
}
if (((uintptr_t) salt) % __alignof__ (uint32_t) != 0)
{
char *tmp = (char *) alloca (salt_len + __alignof__ (uint32_t));
alloca_used += salt_len + __alignof__ (uint32_t);
salt = copied_salt =
memcpy (tmp + __alignof__ (uint32_t)
- ((uintptr_t) tmp) % __alignof__ (uint32_t),
salt, salt_len);
assert (((uintptr_t) salt) % __alignof__ (uint32_t) == 0);
}
#ifdef USE_NSS
/* Initialize libfreebl3. */
NSSLOWInitContext *nss_ictx = NSSLOW_Init ();
if (nss_ictx == NULL)
{
free (free_key);
return NULL;
}
NSSLOWHASHContext *nss_ctx = NULL;
NSSLOWHASHContext *nss_alt_ctx = NULL;
#else
struct sha256_ctx ctx;
struct sha256_ctx alt_ctx;
#endif
/* Prepare for the real work. */
sha256_init_ctx (&ctx, nss_ctx);
/* Add the key string. */
sha256_process_bytes (key, key_len, &ctx, nss_ctx);
/* The last part is the salt string. This must be at most 16
characters and it ends at the first `$' character. */
sha256_process_bytes (salt, salt_len, &ctx, nss_ctx);
/* Compute alternate SHA256 sum with input KEY, SALT, and KEY. The
final result will be added to the first context. */
sha256_init_ctx (&alt_ctx, nss_alt_ctx);
/* Add key. */
sha256_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Add salt. */
sha256_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
/* Add key again. */
sha256_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Now get result of this (32 bytes) and add it to the other
context. */
sha256_finish_ctx (&alt_ctx, nss_alt_ctx, alt_result);
/* Add for any character in the key one byte of the alternate sum. */
for (cnt = key_len; cnt > 32; cnt -= 32)
sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
sha256_process_bytes (alt_result, cnt, &ctx, nss_ctx);
/* Take the binary representation of the length of the key and for every
1 add the alternate sum, for every 0 the key. */
for (cnt = key_len; cnt > 0; cnt >>= 1)
if ((cnt & 1) != 0)
sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
else
sha256_process_bytes (key, key_len, &ctx, nss_ctx);
/* Create intermediate result. */
sha256_finish_ctx (&ctx, nss_ctx, alt_result);
/* Start computation of P byte sequence. */
sha256_init_ctx (&alt_ctx, nss_alt_ctx);
/* For every character in the password add the entire password. */
for (cnt = 0; cnt < key_len; ++cnt)
sha256_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Finish the digest. */
sha256_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
/* Create byte sequence P. */
if (__libc_use_alloca (alloca_used + key_len))
cp = p_bytes = (char *) alloca (key_len);
else
{
free_pbytes = cp = p_bytes = (char *)malloc (key_len);
if (free_pbytes == NULL)
{
free (free_key);
return NULL;
}
}
for (cnt = key_len; cnt >= 32; cnt -= 32)
cp = mempcpy (cp, temp_result, 32);
memcpy (cp, temp_result, cnt);
/* Start computation of S byte sequence. */
sha256_init_ctx (&alt_ctx, nss_alt_ctx);
/* For every character in the password add the entire password. */
for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
sha256_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
/* Finish the digest. */
sha256_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
/* Create byte sequence S. */
cp = s_bytes = alloca (salt_len);
for (cnt = salt_len; cnt >= 32; cnt -= 32)
cp = mempcpy (cp, temp_result, 32);
memcpy (cp, temp_result, cnt);
/* Repeatedly run the collected hash value through SHA256 to burn
CPU cycles. */
for (cnt = 0; cnt < rounds; ++cnt)
{
/* New context. */
sha256_init_ctx (&ctx, nss_ctx);
/* Add key or last result. */
if ((cnt & 1) != 0)
sha256_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
else
sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
/* Add salt for numbers not divisible by 3. */
if (cnt % 3 != 0)
sha256_process_bytes (s_bytes, salt_len, &ctx, nss_ctx);
/* Add key for numbers not divisible by 7. */
if (cnt % 7 != 0)
sha256_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
/* Add key or last result. */
if ((cnt & 1) != 0)
sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
else
sha256_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
/* Create intermediate result. */
sha256_finish_ctx (&ctx, nss_ctx, alt_result);
}
#ifdef USE_NSS
/* Free libfreebl3 resources. */
NSSLOW_Shutdown (nss_ictx);
#endif
/* Now we can construct the result string. It consists of three
parts. */
cp = __stpncpy (buffer, sha256_salt_prefix, MAX (0, buflen));
buflen -= sizeof (sha256_salt_prefix) - 1;
if (rounds_custom)
{
int n = __snprintf (cp, MAX (0, buflen), "%s%zu$",
sha256_rounds_prefix, rounds);
cp += n;
buflen -= n;
}
cp = __stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
if (buflen > 0)
{
*cp++ = '$';
--buflen;
}
__b64_from_24bit (&cp, &buflen,
alt_result[0], alt_result[10], alt_result[20], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[21], alt_result[1], alt_result[11], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[12], alt_result[22], alt_result[2], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[3], alt_result[13], alt_result[23], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[24], alt_result[4], alt_result[14], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[15], alt_result[25], alt_result[5], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[6], alt_result[16], alt_result[26], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[27], alt_result[7], alt_result[17], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[18], alt_result[28], alt_result[8], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[9], alt_result[19], alt_result[29], 4);
__b64_from_24bit (&cp, &buflen,
0, alt_result[31], alt_result[30], 3);
if (buflen <= 0)
{
__set_errno (ERANGE);
buffer = NULL;
}
else
*cp = '\0'; /* Terminate the string. */
/* Clear the buffer for the intermediate result so that people
attaching to processes or reading core dumps cannot get any
information. We do it in this way to clear correct_words[]
inside the SHA256 implementation as well. */
#ifndef USE_NSS
__sha256_init_ctx (&ctx);
__sha256_finish_ctx (&ctx, alt_result);
explicit_bzero (&ctx, sizeof (ctx));
explicit_bzero (&alt_ctx, sizeof (alt_ctx));
#endif
explicit_bzero (temp_result, sizeof (temp_result));
explicit_bzero (p_bytes, key_len);
explicit_bzero (s_bytes, salt_len);
if (copied_key != NULL)
explicit_bzero (copied_key, key_len);
if (copied_salt != NULL)
explicit_bzero (copied_salt, salt_len);
free (free_key);
free (free_pbytes);
return buffer;
}
static char *buffer;
/* This entry point is equivalent to the `crypt' function in Unix
libcs. */
char *
__sha256_crypt (const char *key, const char *salt)
{
/* We don't want to have an arbitrary limit in the size of the
password. We can compute an upper bound for the size of the
result in advance and so we can prepare the buffer we pass to
`sha256_crypt_r'. */
static int buflen;
int needed = (sizeof (sha256_salt_prefix) - 1
+ sizeof (sha256_rounds_prefix) + 9 + 1
+ strlen (salt) + 1 + 43 + 1);
if (buflen < needed)
{
char *new_buffer = (char *) realloc (buffer, needed);
if (new_buffer == NULL)
return NULL;
buffer = new_buffer;
buflen = needed;
}
return __sha256_crypt_r (key, salt, buffer, buflen);
}
static void
__attribute__ ((__destructor__))
free_mem (void)
{
free (buffer);
}

View File

@ -1,193 +0,0 @@
/* Functions to compute SHA256 message digest of files or memory blocks.
according to the definition of SHA256 in FIPS 180-2.
Copyright (C) 2007-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include "sha256.h"
#if __BYTE_ORDER == __LITTLE_ENDIAN
# ifdef _LIBC
# include <byteswap.h>
# define SWAP(n) bswap_32 (n)
# define SWAP64(n) bswap_64 (n)
# else
# define SWAP(n) \
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
# define SWAP64(n) \
(((n) << 56) \
| (((n) & 0xff00) << 40) \
| (((n) & 0xff0000) << 24) \
| (((n) & 0xff000000) << 8) \
| (((n) >> 8) & 0xff000000) \
| (((n) >> 24) & 0xff0000) \
| (((n) >> 40) & 0xff00) \
| ((n) >> 56))
# endif
#else
# define SWAP(n) (n)
# define SWAP64(n) (n)
#endif
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (FIPS 180-2:5.1.1) */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
/* Constants for SHA256 from FIPS 180-2:4.2.2. */
static const uint32_t K[64] =
{
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
void __sha256_process_block (const void *, size_t, struct sha256_ctx *);
/* Initialize structure containing state of computation.
(FIPS 180-2:5.3.2) */
void
__sha256_init_ctx (struct sha256_ctx *ctx)
{
ctx->H[0] = 0x6a09e667;
ctx->H[1] = 0xbb67ae85;
ctx->H[2] = 0x3c6ef372;
ctx->H[3] = 0xa54ff53a;
ctx->H[4] = 0x510e527f;
ctx->H[5] = 0x9b05688c;
ctx->H[6] = 0x1f83d9ab;
ctx->H[7] = 0x5be0cd19;
ctx->total64 = 0;
ctx->buflen = 0;
}
/* Process the remaining bytes in the internal buffer and the usual
prolog according to the standard and write the result to RESBUF.
IMPORTANT: On some systems it is required that RESBUF is correctly
aligned for a 32 bits value. */
void *
__sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
{
/* Take yet unprocessed bytes into account. */
uint32_t bytes = ctx->buflen;
size_t pad;
/* Now count remaining bytes. */
ctx->total64 += bytes;
pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
memcpy (&ctx->buffer[bytes], fillbuf, pad);
/* Put the 64-bit file length in *bits* at the end of the buffer. */
ctx->buffer32[(bytes + pad + 4) / 4] = SWAP (ctx->total[TOTAL64_low] << 3);
ctx->buffer32[(bytes + pad) / 4] = SWAP ((ctx->total[TOTAL64_high] << 3)
| (ctx->total[TOTAL64_low] >> 29));
/* Process last bytes. */
__sha256_process_block (ctx->buffer, bytes + pad + 8, ctx);
/* Put result from CTX in first 32 bytes following RESBUF. */
for (unsigned int i = 0; i < 8; ++i)
((uint32_t *) resbuf)[i] = SWAP (ctx->H[i]);
return resbuf;
}
void
__sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
{
/* When we already have some bits in our internal buffer concatenate
both inputs first. */
if (ctx->buflen != 0)
{
size_t left_over = ctx->buflen;
size_t add = 128 - left_over > len ? len : 128 - left_over;
memcpy (&ctx->buffer[left_over], buffer, add);
ctx->buflen += add;
if (ctx->buflen > 64)
{
__sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
ctx->buflen &= 63;
/* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
ctx->buflen);
}
buffer = (const char *) buffer + add;
len -= add;
}
/* Process available complete blocks. */
if (len >= 64)
{
while (len > 64)
{
__sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
buffer = (const char *) buffer + 64;
len -= 64;
}
}
/* Move remaining bytes into internal buffer. */
if (len > 0)
{
size_t left_over = ctx->buflen;
memcpy (&ctx->buffer[left_over], buffer, len);
left_over += len;
if (left_over >= 64)
{
__sha256_process_block (ctx->buffer, 64, ctx);
left_over -= 64;
memcpy (ctx->buffer, &ctx->buffer[64], left_over);
}
ctx->buflen = left_over;
}
}
#include <sha256-block.c>

View File

@ -1,69 +0,0 @@
/* Declaration of functions and data types used for SHA256 sum computing
library functions.
Copyright (C) 2007-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifndef _SHA256_H
#define _SHA256_H 1
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <endian.h>
/* Structure to save state of computation between the single steps. */
struct sha256_ctx
{
uint32_t H[8];
union
{
uint64_t total64;
#define TOTAL64_low (1 - (BYTE_ORDER == LITTLE_ENDIAN))
#define TOTAL64_high (BYTE_ORDER == LITTLE_ENDIAN)
uint32_t total[2];
};
uint32_t buflen;
union
{
char buffer[128];
uint32_t buffer32[32];
uint64_t buffer64[16];
};
};
/* Initialize structure containing state of computation.
(FIPS 180-2: 5.3.2) */
extern void __sha256_init_ctx (struct sha256_ctx *ctx) __THROW;
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is NOT required that LEN is a multiple of 64. */
extern void __sha256_process_bytes (const void *buffer, size_t len,
struct sha256_ctx *ctx) __THROW;
/* Process the remaining bytes in the buffer and put result from CTX
in first 32 bytes following RESBUF.
IMPORTANT: On some systems it is required that RESBUF is correctly
aligned for a 32 bits value. */
extern void *__sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
__THROW;
#endif /* sha256.h */

View File

@ -1,61 +0,0 @@
#include <crypt.h>
#include <stdio.h>
#include <string.h>
static const struct
{
const char *salt;
const char *input;
const char *expected;
} tests[] =
{
{ "$5$saltstring", "Hello world!",
"$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5" },
{ "$5$rounds=10000$saltstringsaltstring", "Hello world!",
"$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2."
"opqey6IcA" },
{ "$5$rounds=5000$toolongsaltstring", "This is just a test",
"$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8"
"mGRcvxa5" },
{ "$5$rounds=1400$anotherlongsaltstring",
"a very much longer text to encrypt. This one even stretches over more"
"than one line.",
"$5$rounds=1400$anotherlongsalts$Rx.j8H.h8HjEDGomFU8bDkXm3XIUnzyxf12"
"oP84Bnq1" },
{ "$5$rounds=77777$short",
"we have a short salt string but not a short password",
"$5$rounds=77777$short$JiO1O3ZpDAxGJeaDIuqCoEFysAe1mZNJRs3pw0KQRd/" },
{ "$5$rounds=123456$asaltof16chars..", "a short string",
"$5$rounds=123456$asaltof16chars..$gP3VQ/6X7UUEW3HkBn2w1/Ptq2jxPyzV/"
"cZKmF/wJvD" },
{ "$5$rounds=10$roundstoolow", "the minimum number is still observed",
"$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL97"
"2bIC" },
};
#define ntests (sizeof (tests) / sizeof (tests[0]))
static int
do_test (void)
{
int result = 0;
int i;
for (i = 0; i < ntests; ++i)
{
char *cp = crypt (tests[i].input, tests[i].salt);
if (strcmp (cp, tests[i].expected) != 0)
{
printf ("test %d: expected \"%s\", got \"%s\"\n",
i, tests[i].expected, cp);
result = 1;
}
}
return result;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -1,102 +0,0 @@
#include <string.h>
#include "sha256.h"
static const struct
{
const char *input;
const char result[32];
} tests[] =
{
/* Test vectors from FIPS 180-2: appendix B.1. */
{ "abc",
"\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
"\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" },
/* Test vectors from FIPS 180-2: appendix B.2. */
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
"\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
/* Test vectors from the NESSIE project. */
{ "",
"\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24"
"\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55" },
{ "a",
"\xca\x97\x81\x12\xca\x1b\xbd\xca\xfa\xc2\x31\xb3\x9a\x23\xdc\x4d"
"\xa7\x86\xef\xf8\x14\x7c\x4e\x72\xb9\x80\x77\x85\xaf\xee\x48\xbb" },
{ "message digest",
"\xf7\x84\x6f\x55\xcf\x23\xe1\x4e\xeb\xea\xb5\xb4\xe1\x55\x0c\xad"
"\x5b\x50\x9e\x33\x48\xfb\xc4\xef\xa3\xa1\x41\x3d\x39\x3c\xb6\x50" },
{ "abcdefghijklmnopqrstuvwxyz",
"\x71\xc4\x80\xdf\x93\xd6\xae\x2f\x1e\xfa\xd1\x44\x7c\x66\xc9\x52"
"\x5e\x31\x62\x18\xcf\x51\xfc\x8d\x9e\xd8\x32\xf2\xda\xf1\x8b\x73" },
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
"\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"\xdb\x4b\xfc\xbd\x4d\xa0\xcd\x85\xa6\x0c\x3c\x37\xd3\xfb\xd8\x80"
"\x5c\x77\xf1\x5f\xc6\xb1\xfd\xfe\x61\x4e\xe0\xa7\xc8\xfd\xb4\xc0" },
{ "123456789012345678901234567890123456789012345678901234567890"
"12345678901234567890",
"\xf3\x71\xbc\x4a\x31\x1f\x2b\x00\x9e\xef\x95\x2d\xd8\x3c\xa8\x0e"
"\x2b\x60\x02\x6c\x8e\x93\x55\x92\xd0\xf9\xc3\x08\x45\x3c\x81\x3e" }
};
int
main (void)
{
struct sha256_ctx ctx;
char sum[32];
int result = 0;
int cnt;
for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt)
{
__sha256_init_ctx (&ctx);
__sha256_process_bytes (tests[cnt].input, strlen (tests[cnt].input),
&ctx);
__sha256_finish_ctx (&ctx, sum);
if (memcmp (tests[cnt].result, sum, 32) != 0)
{
printf ("test %d run %d failed\n", cnt, 1);
result = 1;
}
__sha256_init_ctx (&ctx);
for (int i = 0; tests[cnt].input[i] != '\0'; ++i)
__sha256_process_bytes (&tests[cnt].input[i], 1, &ctx);
__sha256_finish_ctx (&ctx, sum);
if (memcmp (tests[cnt].result, sum, 32) != 0)
{
printf ("test %d run %d failed\n", cnt, 2);
result = 1;
}
}
/* Test vector from FIPS 180-2: appendix B.3. */
char buf[1000];
memset (buf, 'a', sizeof (buf));
__sha256_init_ctx (&ctx);
for (int i = 0; i < 1000; ++i)
__sha256_process_bytes (buf, sizeof (buf), &ctx);
__sha256_finish_ctx (&ctx, sum);
static const char expected[32] =
"\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
"\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0";
if (memcmp (expected, sum, 32) != 0)
{
printf ("test %d failed\n", cnt++);
result = 1;
}
__sha256_init_ctx (&ctx);
for (int i = 0; i < 100000; ++i)
__sha256_process_bytes (buf, 10, &ctx);
__sha256_finish_ctx (&ctx, sum);
if (memcmp (expected, sum, 32) != 0)
{
printf ("test %d failed\n", cnt++);
result = 1;
}
return result;
}

View File

@ -1,105 +0,0 @@
#include <stdint.h>
/* Process LEN bytes of BUFFER, accumulating context into CTX.
It is assumed that LEN % 128 == 0. */
void
__sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
{
const uint64_t *words = buffer;
size_t nwords = len / sizeof (uint64_t);
uint64_t a = ctx->H[0];
uint64_t b = ctx->H[1];
uint64_t c = ctx->H[2];
uint64_t d = ctx->H[3];
uint64_t e = ctx->H[4];
uint64_t f = ctx->H[5];
uint64_t g = ctx->H[6];
uint64_t h = ctx->H[7];
/* First increment the byte count. FIPS 180-2 specifies the possible
length of the file up to 2^128 bits. Here we only compute the
number of bytes. Do a double word increment. */
#ifdef USE_TOTAL128
ctx->total128 += len;
#else
uint64_t lolen = len;
ctx->total[TOTAL128_low] += lolen;
ctx->total[TOTAL128_high] += ((len >> 31 >> 31 >> 2)
+ (ctx->total[TOTAL128_low] < lolen));
#endif
/* Process all bytes in the buffer with 128 bytes in each round of
the loop. */
while (nwords > 0)
{
uint64_t W[80];
uint64_t a_save = a;
uint64_t b_save = b;
uint64_t c_save = c;
uint64_t d_save = d;
uint64_t e_save = e;
uint64_t f_save = f;
uint64_t g_save = g;
uint64_t h_save = h;
/* Operators defined in FIPS 180-2:4.1.2. */
#define Ch(x, y, z) ((x & y) ^ (~x & z))
#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39))
#define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41))
#define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7))
#define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6))
/* It is unfortunate that C does not provide an operator for
cyclic rotation. Hope the C compiler is smart enough. */
#define CYCLIC(w, s) ((w >> s) | (w << (64 - s)))
/* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */
for (unsigned int t = 0; t < 16; ++t)
{
W[t] = SWAP (*words);
++words;
}
for (unsigned int t = 16; t < 80; ++t)
W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16];
/* The actual computation according to FIPS 180-2:6.3.2 step 3. */
for (unsigned int t = 0; t < 80; ++t)
{
uint64_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t];
uint64_t T2 = S0 (a) + Maj (a, b, c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
}
/* Add the starting values of the context according to FIPS 180-2:6.3.2
step 4. */
a += a_save;
b += b_save;
c += c_save;
d += d_save;
e += e_save;
f += f_save;
g += g_save;
h += h_save;
/* Prepare for the next round. */
nwords -= 16;
}
/* Put checksum in context given as argument. */
ctx->H[0] = a;
ctx->H[1] = b;
ctx->H[2] = c;
ctx->H[3] = d;
ctx->H[4] = e;
ctx->H[5] = f;
ctx->H[6] = g;
ctx->H[7] = h;
}

View File

@ -1,445 +0,0 @@
/* One way encryption based on SHA512 sum.
Copyright (C) 2007-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/param.h>
#include "sha512.h"
#include "crypt-private.h"
#ifdef USE_NSS
typedef int PRBool;
# include <hasht.h>
# include <nsslowhash.h>
# define sha512_init_ctx(ctxp, nss_ctxp) \
do \
{ \
if (((nss_ctxp = NSSLOWHASH_NewContext (nss_ictx, HASH_AlgSHA512)) \
== NULL)) \
{ \
if (nss_ctx != NULL) \
NSSLOWHASH_Destroy (nss_ctx); \
if (nss_alt_ctx != NULL) \
NSSLOWHASH_Destroy (nss_alt_ctx); \
return NULL; \
} \
NSSLOWHASH_Begin (nss_ctxp); \
} \
while (0)
# define sha512_process_bytes(buf, len, ctxp, nss_ctxp) \
NSSLOWHASH_Update (nss_ctxp, (const unsigned char *) buf, len)
# define sha512_finish_ctx(ctxp, nss_ctxp, result) \
do \
{ \
unsigned int ret; \
NSSLOWHASH_End (nss_ctxp, result, &ret, sizeof (result)); \
assert (ret == sizeof (result)); \
NSSLOWHASH_Destroy (nss_ctxp); \
nss_ctxp = NULL; \
} \
while (0)
#else
# define sha512_init_ctx(ctxp, nss_ctxp) \
__sha512_init_ctx (ctxp)
# define sha512_process_bytes(buf, len, ctxp, nss_ctxp) \
__sha512_process_bytes(buf, len, ctxp)
# define sha512_finish_ctx(ctxp, nss_ctxp, result) \
__sha512_finish_ctx (ctxp, result)
#endif
/* Define our magic string to mark salt for SHA512 "encryption"
replacement. */
static const char sha512_salt_prefix[] = "$6$";
/* Prefix for optional rounds specification. */
static const char sha512_rounds_prefix[] = "rounds=";
/* Maximum salt string length. */
#define SALT_LEN_MAX 16
/* Default number of rounds if not explicitly specified. */
#define ROUNDS_DEFAULT 5000
/* Minimum number of rounds. */
#define ROUNDS_MIN 1000
/* Maximum number of rounds. */
#define ROUNDS_MAX 999999999
/* Prototypes for local functions. */
extern char *__sha512_crypt_r (const char *key, const char *salt,
char *buffer, int buflen);
extern char *__sha512_crypt (const char *key, const char *salt);
char *
__sha512_crypt_r (const char *key, const char *salt, char *buffer, int buflen)
{
unsigned char alt_result[64]
__attribute__ ((__aligned__ (__alignof__ (uint64_t))));
unsigned char temp_result[64]
__attribute__ ((__aligned__ (__alignof__ (uint64_t))));
size_t salt_len;
size_t key_len;
size_t cnt;
char *cp;
char *copied_key = NULL;
char *copied_salt = NULL;
char *p_bytes;
char *s_bytes;
/* Default number of rounds. */
size_t rounds = ROUNDS_DEFAULT;
bool rounds_custom = false;
size_t alloca_used = 0;
char *free_key = NULL;
char *free_pbytes = NULL;
/* Find beginning of salt string. The prefix should normally always
be present. Just in case it is not. */
if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
/* Skip salt prefix. */
salt += sizeof (sha512_salt_prefix) - 1;
if (strncmp (salt, sha512_rounds_prefix, sizeof (sha512_rounds_prefix) - 1)
== 0)
{
const char *num = salt + sizeof (sha512_rounds_prefix) - 1;
char *endp;
unsigned long int srounds = strtoul (num, &endp, 10);
if (*endp == '$')
{
salt = endp + 1;
rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
rounds_custom = true;
}
}
salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
key_len = strlen (key);
if (((uintptr_t) key) % __alignof__ (uint64_t) != 0)
{
char *tmp;
if (__libc_use_alloca (alloca_used + key_len + __alignof__ (uint64_t)))
tmp = alloca_account (key_len + __alignof__ (uint64_t), alloca_used);
else
{
free_key = tmp = (char *) malloc (key_len + __alignof__ (uint64_t));
if (tmp == NULL)
return NULL;
}
key = copied_key =
memcpy (tmp + __alignof__ (uint64_t)
- ((uintptr_t) tmp) % __alignof__ (uint64_t),
key, key_len);
assert (((uintptr_t) key) % __alignof__ (uint64_t) == 0);
}
if (((uintptr_t) salt) % __alignof__ (uint64_t) != 0)
{
char *tmp = (char *) alloca (salt_len + __alignof__ (uint64_t));
salt = copied_salt =
memcpy (tmp + __alignof__ (uint64_t)
- ((uintptr_t) tmp) % __alignof__ (uint64_t),
salt, salt_len);
assert (((uintptr_t) salt) % __alignof__ (uint64_t) == 0);
}
#ifdef USE_NSS
/* Initialize libfreebl3. */
NSSLOWInitContext *nss_ictx = NSSLOW_Init ();
if (nss_ictx == NULL)
{
free (free_key);
return NULL;
}
NSSLOWHASHContext *nss_ctx = NULL;
NSSLOWHASHContext *nss_alt_ctx = NULL;
#else
struct sha512_ctx ctx;
struct sha512_ctx alt_ctx;
#endif
/* Prepare for the real work. */
sha512_init_ctx (&ctx, nss_ctx);
/* Add the key string. */
sha512_process_bytes (key, key_len, &ctx, nss_ctx);
/* The last part is the salt string. This must be at most 16
characters and it ends at the first `$' character. */
sha512_process_bytes (salt, salt_len, &ctx, nss_ctx);
/* Compute alternate SHA512 sum with input KEY, SALT, and KEY. The
final result will be added to the first context. */
sha512_init_ctx (&alt_ctx, nss_alt_ctx);
/* Add key. */
sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Add salt. */
sha512_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
/* Add key again. */
sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Now get result of this (64 bytes) and add it to the other
context. */
sha512_finish_ctx (&alt_ctx, nss_alt_ctx, alt_result);
/* Add for any character in the key one byte of the alternate sum. */
for (cnt = key_len; cnt > 64; cnt -= 64)
sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
sha512_process_bytes (alt_result, cnt, &ctx, nss_ctx);
/* Take the binary representation of the length of the key and for every
1 add the alternate sum, for every 0 the key. */
for (cnt = key_len; cnt > 0; cnt >>= 1)
if ((cnt & 1) != 0)
sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
else
sha512_process_bytes (key, key_len, &ctx, nss_ctx);
/* Create intermediate result. */
sha512_finish_ctx (&ctx, nss_ctx, alt_result);
/* Start computation of P byte sequence. */
sha512_init_ctx (&alt_ctx, nss_alt_ctx);
/* For every character in the password add the entire password. */
for (cnt = 0; cnt < key_len; ++cnt)
sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Finish the digest. */
sha512_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
/* Create byte sequence P. */
if (__libc_use_alloca (alloca_used + key_len))
cp = p_bytes = (char *) alloca (key_len);
else
{
free_pbytes = cp = p_bytes = (char *)malloc (key_len);
if (free_pbytes == NULL)
{
free (free_key);
return NULL;
}
}
for (cnt = key_len; cnt >= 64; cnt -= 64)
cp = mempcpy (cp, temp_result, 64);
memcpy (cp, temp_result, cnt);
/* Start computation of S byte sequence. */
sha512_init_ctx (&alt_ctx, nss_alt_ctx);
/* For every character in the password add the entire password. */
for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
sha512_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
/* Finish the digest. */
sha512_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
/* Create byte sequence S. */
cp = s_bytes = alloca (salt_len);
for (cnt = salt_len; cnt >= 64; cnt -= 64)
cp = mempcpy (cp, temp_result, 64);
memcpy (cp, temp_result, cnt);
/* Repeatedly run the collected hash value through SHA512 to burn
CPU cycles. */
for (cnt = 0; cnt < rounds; ++cnt)
{
/* New context. */
sha512_init_ctx (&ctx, nss_ctx);
/* Add key or last result. */
if ((cnt & 1) != 0)
sha512_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
else
sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
/* Add salt for numbers not divisible by 3. */
if (cnt % 3 != 0)
sha512_process_bytes (s_bytes, salt_len, &ctx, nss_ctx);
/* Add key for numbers not divisible by 7. */
if (cnt % 7 != 0)
sha512_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
/* Add key or last result. */
if ((cnt & 1) != 0)
sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
else
sha512_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
/* Create intermediate result. */
sha512_finish_ctx (&ctx, nss_ctx, alt_result);
}
#ifdef USE_NSS
/* Free libfreebl3 resources. */
NSSLOW_Shutdown (nss_ictx);
#endif
/* Now we can construct the result string. It consists of three
parts. */
cp = __stpncpy (buffer, sha512_salt_prefix, MAX (0, buflen));
buflen -= sizeof (sha512_salt_prefix) - 1;
if (rounds_custom)
{
int n = __snprintf (cp, MAX (0, buflen), "%s%zu$",
sha512_rounds_prefix, rounds);
cp += n;
buflen -= n;
}
cp = __stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
if (buflen > 0)
{
*cp++ = '$';
--buflen;
}
__b64_from_24bit (&cp, &buflen,
alt_result[0], alt_result[21], alt_result[42], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[22], alt_result[43], alt_result[1], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[44], alt_result[2], alt_result[23], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[3], alt_result[24], alt_result[45], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[25], alt_result[46], alt_result[4], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[47], alt_result[5], alt_result[26], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[6], alt_result[27], alt_result[48], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[28], alt_result[49], alt_result[7], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[50], alt_result[8], alt_result[29], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[9], alt_result[30], alt_result[51], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[31], alt_result[52], alt_result[10], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[53], alt_result[11], alt_result[32], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[12], alt_result[33], alt_result[54], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[34], alt_result[55], alt_result[13], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[56], alt_result[14], alt_result[35], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[15], alt_result[36], alt_result[57], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[37], alt_result[58], alt_result[16], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[59], alt_result[17], alt_result[38], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[18], alt_result[39], alt_result[60], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[40], alt_result[61], alt_result[19], 4);
__b64_from_24bit (&cp, &buflen,
alt_result[62], alt_result[20], alt_result[41], 4);
__b64_from_24bit (&cp, &buflen,
0, 0, alt_result[63], 2);
if (buflen <= 0)
{
__set_errno (ERANGE);
buffer = NULL;
}
else
*cp = '\0'; /* Terminate the string. */
/* Clear the buffer for the intermediate result so that people
attaching to processes or reading core dumps cannot get any
information. We do it in this way to clear correct_words[]
inside the SHA512 implementation as well. */
#ifndef USE_NSS
__sha512_init_ctx (&ctx);
__sha512_finish_ctx (&ctx, alt_result);
explicit_bzero (&ctx, sizeof (ctx));
explicit_bzero (&alt_ctx, sizeof (alt_ctx));
#endif
explicit_bzero (temp_result, sizeof (temp_result));
explicit_bzero (p_bytes, key_len);
explicit_bzero (s_bytes, salt_len);
if (copied_key != NULL)
explicit_bzero (copied_key, key_len);
if (copied_salt != NULL)
explicit_bzero (copied_salt, salt_len);
free (free_key);
free (free_pbytes);
return buffer;
}
static char *buffer;
/* This entry point is equivalent to the `crypt' function in Unix
libcs. */
char *
__sha512_crypt (const char *key, const char *salt)
{
/* We don't want to have an arbitrary limit in the size of the
password. We can compute an upper bound for the size of the
result in advance and so we can prepare the buffer we pass to
`sha512_crypt_r'. */
static int buflen;
int needed = (sizeof (sha512_salt_prefix) - 1
+ sizeof (sha512_rounds_prefix) + 9 + 1
+ strlen (salt) + 1 + 86 + 1);
if (buflen < needed)
{
char *new_buffer = (char *) realloc (buffer, needed);
if (new_buffer == NULL)
return NULL;
buffer = new_buffer;
buflen = needed;
}
return __sha512_crypt_r (key, salt, buffer, buflen);
}
static void
__attribute__ ((__destructor__))
free_mem (void)
{
free (buffer);
}

View File

@ -1,221 +0,0 @@
/* Functions to compute SHA512 message digest of files or memory blocks.
according to the definition of SHA512 in FIPS 180-2.
Copyright (C) 2007-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include "sha512.h"
#if __BYTE_ORDER == __LITTLE_ENDIAN
# ifdef _LIBC
# include <byteswap.h>
# define SWAP(n) bswap_64 (n)
# else
# define SWAP(n) \
(((n) << 56) \
| (((n) & 0xff00) << 40) \
| (((n) & 0xff0000) << 24) \
| (((n) & 0xff000000) << 8) \
| (((n) >> 8) & 0xff000000) \
| (((n) >> 24) & 0xff0000) \
| (((n) >> 40) & 0xff00) \
| ((n) >> 56))
# endif
#else
# define SWAP(n) (n)
#endif
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (FIPS 180-2:5.1.2) */
static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ };
/* Constants for SHA512 from FIPS 180-2:4.2.3. */
static const uint64_t K[80] =
{
UINT64_C (0x428a2f98d728ae22), UINT64_C (0x7137449123ef65cd),
UINT64_C (0xb5c0fbcfec4d3b2f), UINT64_C (0xe9b5dba58189dbbc),
UINT64_C (0x3956c25bf348b538), UINT64_C (0x59f111f1b605d019),
UINT64_C (0x923f82a4af194f9b), UINT64_C (0xab1c5ed5da6d8118),
UINT64_C (0xd807aa98a3030242), UINT64_C (0x12835b0145706fbe),
UINT64_C (0x243185be4ee4b28c), UINT64_C (0x550c7dc3d5ffb4e2),
UINT64_C (0x72be5d74f27b896f), UINT64_C (0x80deb1fe3b1696b1),
UINT64_C (0x9bdc06a725c71235), UINT64_C (0xc19bf174cf692694),
UINT64_C (0xe49b69c19ef14ad2), UINT64_C (0xefbe4786384f25e3),
UINT64_C (0x0fc19dc68b8cd5b5), UINT64_C (0x240ca1cc77ac9c65),
UINT64_C (0x2de92c6f592b0275), UINT64_C (0x4a7484aa6ea6e483),
UINT64_C (0x5cb0a9dcbd41fbd4), UINT64_C (0x76f988da831153b5),
UINT64_C (0x983e5152ee66dfab), UINT64_C (0xa831c66d2db43210),
UINT64_C (0xb00327c898fb213f), UINT64_C (0xbf597fc7beef0ee4),
UINT64_C (0xc6e00bf33da88fc2), UINT64_C (0xd5a79147930aa725),
UINT64_C (0x06ca6351e003826f), UINT64_C (0x142929670a0e6e70),
UINT64_C (0x27b70a8546d22ffc), UINT64_C (0x2e1b21385c26c926),
UINT64_C (0x4d2c6dfc5ac42aed), UINT64_C (0x53380d139d95b3df),
UINT64_C (0x650a73548baf63de), UINT64_C (0x766a0abb3c77b2a8),
UINT64_C (0x81c2c92e47edaee6), UINT64_C (0x92722c851482353b),
UINT64_C (0xa2bfe8a14cf10364), UINT64_C (0xa81a664bbc423001),
UINT64_C (0xc24b8b70d0f89791), UINT64_C (0xc76c51a30654be30),
UINT64_C (0xd192e819d6ef5218), UINT64_C (0xd69906245565a910),
UINT64_C (0xf40e35855771202a), UINT64_C (0x106aa07032bbd1b8),
UINT64_C (0x19a4c116b8d2d0c8), UINT64_C (0x1e376c085141ab53),
UINT64_C (0x2748774cdf8eeb99), UINT64_C (0x34b0bcb5e19b48a8),
UINT64_C (0x391c0cb3c5c95a63), UINT64_C (0x4ed8aa4ae3418acb),
UINT64_C (0x5b9cca4f7763e373), UINT64_C (0x682e6ff3d6b2b8a3),
UINT64_C (0x748f82ee5defb2fc), UINT64_C (0x78a5636f43172f60),
UINT64_C (0x84c87814a1f0ab72), UINT64_C (0x8cc702081a6439ec),
UINT64_C (0x90befffa23631e28), UINT64_C (0xa4506cebde82bde9),
UINT64_C (0xbef9a3f7b2c67915), UINT64_C (0xc67178f2e372532b),
UINT64_C (0xca273eceea26619c), UINT64_C (0xd186b8c721c0c207),
UINT64_C (0xeada7dd6cde0eb1e), UINT64_C (0xf57d4f7fee6ed178),
UINT64_C (0x06f067aa72176fba), UINT64_C (0x0a637dc5a2c898a6),
UINT64_C (0x113f9804bef90dae), UINT64_C (0x1b710b35131c471b),
UINT64_C (0x28db77f523047d84), UINT64_C (0x32caab7b40c72493),
UINT64_C (0x3c9ebe0a15c9bebc), UINT64_C (0x431d67c49c100d4c),
UINT64_C (0x4cc5d4becb3e42b6), UINT64_C (0x597f299cfc657e2a),
UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817)
};
void __sha512_process_block (const void *buffer, size_t len,
struct sha512_ctx *ctx);
/* Initialize structure containing state of computation.
(FIPS 180-2:5.3.3) */
void
__sha512_init_ctx (struct sha512_ctx *ctx)
{
ctx->H[0] = UINT64_C (0x6a09e667f3bcc908);
ctx->H[1] = UINT64_C (0xbb67ae8584caa73b);
ctx->H[2] = UINT64_C (0x3c6ef372fe94f82b);
ctx->H[3] = UINT64_C (0xa54ff53a5f1d36f1);
ctx->H[4] = UINT64_C (0x510e527fade682d1);
ctx->H[5] = UINT64_C (0x9b05688c2b3e6c1f);
ctx->H[6] = UINT64_C (0x1f83d9abfb41bd6b);
ctx->H[7] = UINT64_C (0x5be0cd19137e2179);
ctx->total[0] = ctx->total[1] = 0;
ctx->buflen = 0;
}
/* Process the remaining bytes in the internal buffer and the usual
prolog according to the standard and write the result to RESBUF.
IMPORTANT: On some systems it is required that RESBUF is correctly
aligned for a 32 bits value. */
void *
__sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
{
/* Take yet unprocessed bytes into account. */
uint64_t bytes = ctx->buflen;
size_t pad;
/* Now count remaining bytes. */
#ifdef USE_TOTAL128
ctx->total128 += bytes;
#else
ctx->total[TOTAL128_low] += bytes;
if (ctx->total[TOTAL128_low] < bytes)
++ctx->total[TOTAL128_high];
#endif
pad = bytes >= 112 ? 128 + 112 - bytes : 112 - bytes;
memcpy (&ctx->buffer[bytes], fillbuf, pad);
/* Put the 128-bit file length in *bits* at the end of the buffer. */
ctx->buffer64[(bytes + pad + 8) / 8] = SWAP (ctx->total[TOTAL128_low] << 3);
ctx->buffer64[(bytes + pad) / 8] = SWAP ((ctx->total[TOTAL128_high] << 3)
| (ctx->total[TOTAL128_low] >> 61));
/* Process last bytes. */
__sha512_process_block (ctx->buffer, bytes + pad + 16, ctx);
/* Put result from CTX in first 64 bytes following RESBUF. */
for (unsigned int i = 0; i < 8; ++i)
((uint64_t *) resbuf)[i] = SWAP (ctx->H[i]);
return resbuf;
}
void
__sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
{
/* When we already have some bits in our internal buffer concatenate
both inputs first. */
if (ctx->buflen != 0)
{
size_t left_over = ctx->buflen;
size_t add = 256 - left_over > len ? len : 256 - left_over;
memcpy (&ctx->buffer[left_over], buffer, add);
ctx->buflen += add;
if (ctx->buflen > 128)
{
__sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx);
ctx->buflen &= 127;
/* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~127],
ctx->buflen);
}
buffer = (const char *) buffer + add;
len -= add;
}
/* Process available complete blocks. */
if (len >= 128)
{
while (len > 128)
{
__sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128,
ctx);
buffer = (const char *) buffer + 128;
len -= 128;
}
}
/* Move remaining bytes into internal buffer. */
if (len > 0)
{
size_t left_over = ctx->buflen;
memcpy (&ctx->buffer[left_over], buffer, len);
left_over += len;
if (left_over >= 128)
{
__sha512_process_block (ctx->buffer, 128, ctx);
left_over -= 128;
memcpy (ctx->buffer, &ctx->buffer[128], left_over);
}
ctx->buflen = left_over;
}
}
#include <sha512-block.c>

View File

@ -1,72 +0,0 @@
/* Declaration of functions and data types used for SHA512 sum computing
library functions.
Copyright (C) 2007-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifndef _SHA512_H
#define _SHA512_H 1
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <endian.h>
#include <bits/wordsize.h>
/* Structure to save state of computation between the single steps. */
struct sha512_ctx
{
uint64_t H[8];
union
{
#if defined __GNUC__ && __WORDSIZE == 64
# define USE_TOTAL128
unsigned int total128 __attribute__ ((__mode__ (TI)));
#endif
#define TOTAL128_low (1 - (BYTE_ORDER == LITTLE_ENDIAN))
#define TOTAL128_high (BYTE_ORDER == LITTLE_ENDIAN)
uint64_t total[2];
};
uint64_t buflen;
union
{
char buffer[256];
uint64_t buffer64[32];
};
};
/* Initialize structure containing state of computation.
(FIPS 180-2: 5.3.3) */
extern void __sha512_init_ctx (struct sha512_ctx *ctx) __THROW;
/* Starting with the result of former calls of this function (or the
initialization function update the context for the next LEN bytes
starting at BUFFER.
It is NOT required that LEN is a multiple of 128. */
extern void __sha512_process_bytes (const void *buffer, size_t len,
struct sha512_ctx *ctx) __THROW;
/* Process the remaining bytes in the buffer and put result from CTX
in first 64 bytes following RESBUF.
IMPORTANT: On some systems it is required that RESBUF is correctly
aligned for a 64 bits value. */
extern void *__sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
__THROW;
#endif /* sha512.h */

View File

@ -1,63 +0,0 @@
#include <crypt.h>
#include <stdio.h>
#include <string.h>
static const struct
{
const char *salt;
const char *input;
const char *expected;
} tests[] =
{
{ "$6$saltstring", "Hello world!",
"$6$saltstring$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu"
"esI68u4OTLiBFdcbYEdFCoEOfaS35inz1" },
{ "$6$rounds=10000$saltstringsaltstring", "Hello world!",
"$6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sb"
"HbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v." },
{ "$6$rounds=5000$toolongsaltstring", "This is just a test",
"$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQ"
"zQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0" },
{ "$6$rounds=1400$anotherlongsaltstring",
"a very much longer text to encrypt. This one even stretches over more"
"than one line.",
"$6$rounds=1400$anotherlongsalts$POfYwTEok97VWcjxIiSOjiykti.o/pQs.wP"
"vMxQ6Fm7I6IoYN3CmLs66x9t0oSwbtEW7o7UmJEiDwGqd8p4ur1" },
{ "$6$rounds=77777$short",
"we have a short salt string but not a short password",
"$6$rounds=77777$short$WuQyW2YR.hBNpjjRhpYD/ifIw05xdfeEyQoMxIXbkvr0g"
"ge1a1x3yRULJ5CCaUeOxFmtlcGZelFl5CxtgfiAc0" },
{ "$6$rounds=123456$asaltof16chars..", "a short string",
"$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwc"
"elCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1" },
{ "$6$rounds=10$roundstoolow", "the minimum number is still observed",
"$6$rounds=1000$roundstoolow$kUMsbe306n21p9R.FRkW3IGn.S9NPN0x50YhH1x"
"hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX." },
};
#define ntests (sizeof (tests) / sizeof (tests[0]))
static int
do_test (void)
{
int result = 0;
int i;
for (i = 0; i < ntests; ++i)
{
char *cp = crypt (tests[i].input, tests[i].salt);
if (strcmp (cp, tests[i].expected) != 0)
{
printf ("test %d: expected \"%s\", got \"%s\"\n",
i, tests[i].expected, cp);
result = 1;
}
}
return result;
}
#define TIMEOUT 32
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -1,113 +0,0 @@
#include <string.h>
#include "sha512.h"
static const struct
{
const char *input;
const char result[64];
} tests[] =
{
/* Test vectors from FIPS 180-2: appendix C.1. */
{ "abc",
"\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31"
"\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a"
"\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd"
"\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f" },
/* Test vectors from FIPS 180-2: appendix C.2. */
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
"\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f"
"\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18"
"\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a"
"\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09" },
/* Test vectors from the NESSIE project. */
{ "",
"\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07"
"\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce"
"\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f"
"\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e" },
{ "a",
"\x1f\x40\xfc\x92\xda\x24\x16\x94\x75\x09\x79\xee\x6c\xf5\x82\xf2"
"\xd5\xd7\xd2\x8e\x18\x33\x5d\xe0\x5a\xbc\x54\xd0\x56\x0e\x0f\x53"
"\x02\x86\x0c\x65\x2b\xf0\x8d\x56\x02\x52\xaa\x5e\x74\x21\x05\x46"
"\xf3\x69\xfb\xbb\xce\x8c\x12\xcf\xc7\x95\x7b\x26\x52\xfe\x9a\x75" },
{ "message digest",
"\x10\x7d\xbf\x38\x9d\x9e\x9f\x71\xa3\xa9\x5f\x6c\x05\x5b\x92\x51"
"\xbc\x52\x68\xc2\xbe\x16\xd6\xc1\x34\x92\xea\x45\xb0\x19\x9f\x33"
"\x09\xe1\x64\x55\xab\x1e\x96\x11\x8e\x8a\x90\x5d\x55\x97\xb7\x20"
"\x38\xdd\xb3\x72\xa8\x98\x26\x04\x6d\xe6\x66\x87\xbb\x42\x0e\x7c" },
{ "abcdefghijklmnopqrstuvwxyz",
"\x4d\xbf\xf8\x6c\xc2\xca\x1b\xae\x1e\x16\x46\x8a\x05\xcb\x98\x81"
"\xc9\x7f\x17\x53\xbc\xe3\x61\x90\x34\x89\x8f\xaa\x1a\xab\xe4\x29"
"\x95\x5a\x1b\xf8\xec\x48\x3d\x74\x21\xfe\x3c\x16\x46\x61\x3a\x59"
"\xed\x54\x41\xfb\x0f\x32\x13\x89\xf7\x7f\x48\xa8\x79\xc7\xb1\xf1" },
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"\x20\x4a\x8f\xc6\xdd\xa8\x2f\x0a\x0c\xed\x7b\xeb\x8e\x08\xa4\x16"
"\x57\xc1\x6e\xf4\x68\xb2\x28\xa8\x27\x9b\xe3\x31\xa7\x03\xc3\x35"
"\x96\xfd\x15\xc1\x3b\x1b\x07\xf9\xaa\x1d\x3b\xea\x57\x78\x9c\xa0"
"\x31\xad\x85\xc7\xa7\x1d\xd7\x03\x54\xec\x63\x12\x38\xca\x34\x45" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"\x1e\x07\xbe\x23\xc2\x6a\x86\xea\x37\xea\x81\x0c\x8e\xc7\x80\x93"
"\x52\x51\x5a\x97\x0e\x92\x53\xc2\x6f\x53\x6c\xfc\x7a\x99\x96\xc4"
"\x5c\x83\x70\x58\x3e\x0a\x78\xfa\x4a\x90\x04\x1d\x71\xa4\xce\xab"
"\x74\x23\xf1\x9c\x71\xb9\xd5\xa3\xe0\x12\x49\xf0\xbe\xbd\x58\x94" },
{ "123456789012345678901234567890123456789012345678901234567890"
"12345678901234567890",
"\x72\xec\x1e\xf1\x12\x4a\x45\xb0\x47\xe8\xb7\xc7\x5a\x93\x21\x95"
"\x13\x5b\xb6\x1d\xe2\x4e\xc0\xd1\x91\x40\x42\x24\x6e\x0a\xec\x3a"
"\x23\x54\xe0\x93\xd7\x6f\x30\x48\xb4\x56\x76\x43\x46\x90\x0c\xb1"
"\x30\xd2\xa4\xfd\x5d\xd1\x6a\xbb\x5e\x30\xbc\xb8\x50\xde\xe8\x43" }
};
int
main (void)
{
struct sha512_ctx ctx;
char sum[64];
int result = 0;
int cnt;
for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt)
{
__sha512_init_ctx (&ctx);
__sha512_process_bytes (tests[cnt].input, strlen (tests[cnt].input),
&ctx);
__sha512_finish_ctx (&ctx, sum);
if (memcmp (tests[cnt].result, sum, 64) != 0)
{
printf ("test %d run %d failed\n", cnt, 1);
result = 1;
}
__sha512_init_ctx (&ctx);
for (int i = 0; tests[cnt].input[i] != '\0'; ++i)
__sha512_process_bytes (&tests[cnt].input[i], 1, &ctx);
__sha512_finish_ctx (&ctx, sum);
if (memcmp (tests[cnt].result, sum, 64) != 0)
{
printf ("test %d run %d failed\n", cnt, 2);
result = 1;
}
}
/* Test vector from FIPS 180-2: appendix C.3. */
char buf[1000];
memset (buf, 'a', sizeof (buf));
__sha512_init_ctx (&ctx);
for (int i = 0; i < 1000; ++i)
__sha512_process_bytes (buf, sizeof (buf), &ctx);
__sha512_finish_ctx (&ctx, sum);
static const char expected[64] =
"\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63"
"\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb"
"\xde\x0f\xf2\x44\x87\x7e\xa6\x0a\x4c\xb0\x43\x2c\xe5\x77\xc3\x1b"
"\xeb\x00\x9c\x5c\x2c\x49\xaa\x2e\x4e\xad\xb2\x17\xad\x8c\xc0\x9b";
if (memcmp (expected, sum, 64) != 0)
{
printf ("test %d failed\n", cnt);
result = 1;
}
return result;
}

View File

@ -1,153 +0,0 @@
/*
* This fcrypt/crypt speed testing program
* is derived from one floating around in
* the net. It's distributed along with
* UFC-crypt but is not covered by any
* licence.
*
* @(#)speeds.c 1.11 20 Aug 1996
*/
#include <signal.h>
#include <stdio.h>
#ifndef SIGVTALRM
/*
* patch from chip@chinacat.unicom.com (Chip Rosenthal):
* you may enable it if your system does not include
* a setitimer() function. You'll have to ensure the
* existence an environment variable: HZ giving how many
* ticks goes per second.
* If not existing in your default environment 50, 60
* or even 100 may be the right value. Perhaps you should
* then use 'time ./ufc 10000' instead of guessing.
*/
#define NO_ITIMER
#endif
#ifdef NO_ITIMER
#include <sys/types.h>
#include <sys/times.h>
#else
#include <sys/time.h>
#endif
static int cnt;
#ifdef NO_ITIMER
char *hz;
struct tms tstart, tfinish;
#endif
#define ITIME 10 /* Number of seconds to run test. */
char *crypt(), *fcrypt();
void
Stop (void)
{
double elapsed;
#ifdef NO_ITIMER
(void) times(&tfinish);
elapsed = ((tfinish.tms_utime + tfinish.tms_stime) -
(tstart.tms_utime + tstart.tms_stime)) / atoi(hz);
printf("elapsed time = %d sec, CPU time = %f sec\n", ITIME, elapsed);
#else
elapsed = ITIME;
#endif
printf ("Did %f %s()s per second.\n", ((float) cnt) / elapsed,
#if defined(FCRYPT)
"fcrypt"
#else
"crypt"
#endif
);
exit (0);
}
/*
* Silly rewrite of 'bzero'. I do so
* because some machines don't have
* bzero and some don't have memset.
*/
static void clearmem(start, cnt)
char *start;
int cnt;
{ while(cnt--)
*start++ = '\0';
}
main (void)
{
char *s;
#ifdef NO_ITIMER
extern char *getenv();
#else
struct itimerval itv;
#endif
#ifdef NO_ITIMER
if ((hz = getenv("HZ")) == NULL) {
fprintf(stderr, "HZ environment parameter undefined\n");
exit(1);
}
#endif
#ifdef FCRYPT
printf("\n");
printf("Warning: this version of the speed program may run slower when\n");
printf("benchmarking UFC-crypt than previous versions. This is because it\n");
printf("stresses the CPU hardware cache in order to get benchmark figures\n");
printf("that corresponds closer to the performance that can be expected in\n");
printf("a password cracker.\n\n");
#endif
printf ("Running %s for %d seconds of virtual time ...\n",
#ifdef FCRYPT
"UFC-crypt",
#else
"crypt(libc)",
#endif
ITIME);
#ifdef FCRYPT
init_des ();
#endif
#ifdef NO_ITIMER
signal(SIGALRM, Stop);
switch (fork()) {
case -1:
perror("fork failed");
exit(1);
case 0:
sleep(10);
kill(getppid(), SIGALRM);
exit(0);
default:
(void) times(&tstart);
}
#else
clearmem ((char*)&itv, (int)sizeof (itv));
signal (SIGVTALRM, Stop);
itv.it_value.tv_sec = ITIME;
itv.it_value.tv_usec = 0;
setitimer (ITIMER_VIRTUAL, &itv, NULL);
#endif
s = "fredred";
for (cnt = 0;; cnt++)
{
#ifdef FCRYPT
s = fcrypt (s, "eek");
#else
s = crypt (s, "eek");
#endif
}
}

View File

@ -1,28 +0,0 @@
/* Types for UFC-crypt.
Copyright (C) 1998-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <stdint.h>
typedef uint_fast32_t ufc_long;
typedef uint64_t long64;
typedef uint32_t long32;
#if UINT_FAST32_MAX == UINT_FAST64_MAX
# define _UFC_64_
#else
# define _UFC_32_
#endif

View File

@ -1,54 +0,0 @@
/*
* UFC-crypt: ultra fast crypt(3) implementation
*
* Copyright (C) 1991-2023 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the GNU C Library; see the file COPYING.LIB. If not,
* see <https://www.gnu.org/licenses/>.
*
* @(#)ufc.c 2.7 9/10/96
*
* Stub main program for debugging
* and benchmarking.
*
*/
#include <stdio.h>
char *crypt();
main(argc, argv)
int argc;
char **argv;
{ char *s;
unsigned long i,iterations;
if(argc != 2) {
fprintf(stderr, "usage: ufc iterations\n");
exit(1);
}
argv++;
iterations = atoi(*argv);
printf("ufc: running %d iterations\n", iterations);
for(i=0; i<iterations; i++)
s=crypt("foob","ar");
if(strcmp(s, "arlEKn0OzVJn.") == 0)
printf("OK\n");
else {
printf("wrong result: %s!!\n", s);
exit(1);
}
exit(0);
}

View File

@ -1217,23 +1217,6 @@ $(objpfx)tst-_dl_addr_inside_object: $(objpfx)dl-addr-obj.os
CFLAGS-tst-_dl_addr_inside_object.c += $(PIE-ccflag) CFLAGS-tst-_dl_addr_inside_object.c += $(PIE-ccflag)
endif endif
# We can only test static libcrypt use if libcrypt has been built,
# and either NSS crypto is not in use, or static NSS libraries are
# available.
ifeq ($(build-crypt),no)
CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0
else
ifeq ($(nss-crypt),no)
CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1
else
ifeq ($(static-nss-crypt),no)
CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=0
else
CFLAGS-tst-linkall-static.c += -DUSE_CRYPT=1
endif
endif
endif
include ../Rules include ../Rules
ifeq (yes,$(build-shared)) ifeq (yes,$(build-shared))
@ -1951,9 +1934,6 @@ endif
ifeq ($(have-thread-library),yes) ifeq ($(have-thread-library),yes)
localplt-built-dso += $(filter-out %_nonshared.a, $(shared-thread-library)) localplt-built-dso += $(filter-out %_nonshared.a, $(shared-thread-library))
endif endif
ifeq ($(build-crypt),yes)
localplt-built-dso += $(addprefix $(common-objpfx), crypt/libcrypt.so)
endif
ifneq ($(pthread-in-libc),yes) ifneq ($(pthread-in-libc),yes)
localplt-built-dso += $(addprefix $(common-objpfx), rt/librt.so) localplt-built-dso += $(addprefix $(common-objpfx), rt/librt.so)
endif endif
@ -2438,24 +2418,6 @@ $(objpfx)tst-linkall-static: \
$(common-objpfx)rt/librt.a \ $(common-objpfx)rt/librt.a \
$(static-thread-library) $(static-thread-library)
ifeq ($(build-crypt),yes)
# If we are using NSS crypto and we have the ability to link statically
# then we include libcrypt.a, otherwise we leave out libcrypt.a and
# link as much as we can into the tst-linkall-static test. This assumes
# that linking with libcrypt.a does everything required to include the
# static NSS crypto library.
ifeq (yesyes,$(nss-crypt)$(static-nss-crypt))
$(objpfx)tst-linkall-static: \
$(common-objpfx)crypt/libcrypt.a
endif
# If we are not using NSS crypto then we always have the ability to link
# with libcrypt.a.
ifeq (no,$(nss-crypt))
$(objpfx)tst-linkall-static: \
$(common-objpfx)crypt/libcrypt.a
endif
endif
LDFLAGS-nextmod3.so = -Wl,--version-script=nextmod3.map LDFLAGS-nextmod3.so = -Wl,--version-script=nextmod3.map
# The application depends on the DSO, and the DSO loads the plugin. # The application depends on the DSO, and the DSO loads the plugin.

View File

@ -18,9 +18,6 @@
#include <math.h> #include <math.h>
#include <pthread.h> #include <pthread.h>
#if USE_CRYPT
# include <crypt.h>
#endif
#include <resolv.h> #include <resolv.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <utmp.h> #include <utmp.h>
@ -34,9 +31,6 @@ void *references[] =
{ {
&pow, /* libm */ &pow, /* libm */
&pthread_create, /* libpthread */ &pthread_create, /* libpthread */
#if USE_CRYPT
&crypt, /* libcrypt */
#endif
&res_send, /* libresolv */ &res_send, /* libresolv */
&dlopen, /* libdl */ &dlopen, /* libdl */
&login, /* libutil */ &login, /* libutil */

View File

@ -1,3 +0,0 @@
#ifndef _CRYPT_H
# include <crypt/crypt.h>
#endif /* _CRYPT_H */

View File

@ -47,7 +47,7 @@ extra-libs-others = $(extra-libs)
libBrokenLocale-routines = broken_cur_max libBrokenLocale-routines = broken_cur_max
subdir-dirs = programs subdir-dirs = programs
vpath %.c programs ../crypt vpath %.c programs
vpath %.h programs vpath %.h programs
vpath %.gperf programs vpath %.gperf programs
@ -69,8 +69,6 @@ endif
include ../Rules include ../Rules
CFLAGS-md5.c += -I../crypt
programs/%-kw.h: programs/%-kw.gperf programs/%-kw.h: programs/%-kw.gperf
cd programs \ cd programs \
&& $(GPERF) $(GPERFFLAGS) -N $(@F:-kw.h=_hash) $(<F) > $(@F).new && $(GPERF) $(GPERFFLAGS) -N $(@F:-kw.h=_hash) $(<F) > $(@F).new

View File

@ -41,7 +41,7 @@
#include <libc-mmap.h> #include <libc-mmap.h>
#include <libc-pointer-arith.h> #include <libc-pointer-arith.h>
#include "../../crypt/md5.h" #include "md5.h"
#include "../localeinfo.h" #include "../localeinfo.h"
#include "../locarchive.h" #include "../locarchive.h"
#include "localedef.h" #include "localedef.h"

View File

@ -30,13 +30,13 @@
#include <assert.h> #include <assert.h>
#include <wchar.h> #include <wchar.h>
#include "../../crypt/md5.h"
#include "localedef.h" #include "localedef.h"
#include "localeinfo.h" #include "localeinfo.h"
#include "locfile.h" #include "locfile.h"
#include "simple-hash.h" #include "simple-hash.h"
#include "locfile-kw.h" #include "locfile-kw.h"
#include "md5.h"
#define obstack_chunk_alloc xmalloc #define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free #define obstack_chunk_free free

View File

@ -19,36 +19,12 @@
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */ /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
#ifdef HAVE_CONFIG_H #include <string.h>
# include <config.h> #include <endian.h>
#endif
#include <sys/types.h>
#if STDC_HEADERS || defined _LIBC
# include <stdlib.h>
# include <string.h>
#else
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) (bcopy ((s), (d), (n)), (d))
# endif
#endif
#include "md5.h" #include "md5.h"
#ifdef _LIBC #if __BYTE_ORDER == __BIG_ENDIAN
# include <endian.h>
# if __BYTE_ORDER == __BIG_ENDIAN
# define WORDS_BIGENDIAN 1 # define WORDS_BIGENDIAN 1
# endif
/* We need to keep the namespace clean so define the MD5 function
protected using leading __ . */
# define md5_init_ctx __md5_init_ctx
# define md5_process_bytes __md5_process_bytes
# define md5_finish_ctx __md5_finish_ctx
# define md5_read_ctx __md5_read_ctx
# define md5_stream __md5_stream
# define md5_buffer __md5_buffer
#endif #endif
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
@ -67,7 +43,7 @@ static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
/* Initialize structure containing state of computation. /* Initialize structure containing state of computation.
(RFC 1321, 3.3: Step 3) */ (RFC 1321, 3.3: Step 3) */
void void
md5_init_ctx (struct md5_ctx *ctx) __md5_init_ctx (struct md5_ctx *ctx)
{ {
ctx->A = 0x67452301; ctx->A = 0x67452301;
ctx->B = 0xefcdab89; ctx->B = 0xefcdab89;
@ -84,7 +60,7 @@ md5_init_ctx (struct md5_ctx *ctx)
IMPORTANT: On some systems it is required that RESBUF is correctly IMPORTANT: On some systems it is required that RESBUF is correctly
aligned for a 32 bits value. */ aligned for a 32 bits value. */
void * void *
md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) __md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
{ {
((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
@ -100,7 +76,7 @@ md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
IMPORTANT: On some systems it is required that RESBUF is correctly IMPORTANT: On some systems it is required that RESBUF is correctly
aligned for a 32 bits value. */ aligned for a 32 bits value. */
void * void *
md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) __md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
{ {
/* Take yet unprocessed bytes into account. */ /* Take yet unprocessed bytes into account. */
md5_uint32 bytes = ctx->buflen; md5_uint32 bytes = ctx->buflen;
@ -122,61 +98,7 @@ md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
/* Process last bytes. */ /* Process last bytes. */
__md5_process_block (ctx->buffer, bytes + pad + 8, ctx); __md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
return md5_read_ctx (ctx, resbuf); return __md5_read_ctx (ctx, resbuf);
}
/* Compute MD5 message digest for bytes read from STREAM. The
resulting message digest number will be written into the 16 bytes
beginning at RESBLOCK. */
int
md5_stream (FILE *stream, void *resblock)
{
/* Important: BLOCKSIZE must be a multiple of 64. */
#define BLOCKSIZE 4096
struct md5_ctx ctx;
char buffer[BLOCKSIZE + 72];
size_t sum;
/* Initialize the computation context. */
md5_init_ctx (&ctx);
/* Iterate over full file contents. */
while (1)
{
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
computation function processes the whole buffer so that with the
next round of the loop another block can be read. */
size_t n;
sum = 0;
/* Read block. Take care for partial reads. */
do
{
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
sum += n;
}
while (sum < BLOCKSIZE && n != 0);
if (n == 0 && ferror (stream))
return 1;
/* If end of file is reached, end the loop. */
if (n == 0)
break;
/* Process buffer with BLOCKSIZE bytes. Note that
BLOCKSIZE % 64 == 0
*/
__md5_process_block (buffer, BLOCKSIZE, &ctx);
}
/* Add the last bytes if necessary. */
if (sum > 0)
md5_process_bytes (buffer, sum, &ctx);
/* Construct result in desired memory. */
md5_finish_ctx (&ctx, resblock);
return 0;
} }
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
@ -184,23 +106,23 @@ md5_stream (FILE *stream, void *resblock)
output yields to the wanted ASCII representation of the message output yields to the wanted ASCII representation of the message
digest. */ digest. */
void * void *
md5_buffer (const char *buffer, size_t len, void *resblock) __md5_buffer (const char *buffer, size_t len, void *resblock)
{ {
struct md5_ctx ctx; struct md5_ctx ctx;
/* Initialize the computation context. */ /* Initialize the computation context. */
md5_init_ctx (&ctx); __md5_init_ctx (&ctx);
/* Process whole buffer but last len % 64 bytes. */ /* Process whole buffer but last len % 64 bytes. */
md5_process_bytes (buffer, len, &ctx); __md5_process_bytes (buffer, len, &ctx);
/* Put result in desired memory area. */ /* Put result in desired memory area. */
return md5_finish_ctx (&ctx, resblock); return __md5_finish_ctx (&ctx, resblock);
} }
void void
md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx) __md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
{ {
/* When we already have some bits in our internal buffer concatenate /* When we already have some bits in our internal buffer concatenate
both inputs first. */ both inputs first. */

View File

@ -20,12 +20,6 @@
#ifndef _MD5_H #ifndef _MD5_H
#define _MD5_H 1 #define _MD5_H 1
#include <stdio.h>
#if defined HAVE_LIMITS_H || defined _LIBC
# include <limits.h>
#endif
#define MD5_DIGEST_SIZE 16 #define MD5_DIGEST_SIZE 16
#define MD5_BLOCK_SIZE 64 #define MD5_BLOCK_SIZE 64
@ -36,41 +30,9 @@
the resulting executable. Locally running cross-compiled executables the resulting executable. Locally running cross-compiled executables
is usually not possible. */ is usually not possible. */
#ifdef _LIBC #include <stdint.h>
# include <stdint.h>
typedef uint32_t md5_uint32; typedef uint32_t md5_uint32;
typedef uintptr_t md5_uintptr; typedef uintptr_t md5_uintptr;
#else
# define UINT_MAX_32_BITS 4294967295U
/* If UINT_MAX isn't defined, assume it's a 32-bit type.
This should be valid for all systems GNU cares about because
that doesn't include 16-bit systems, and only modern systems
(that certainly have <limits.h>) have 64+-bit integral types. */
# ifndef UINT_MAX
# define UINT_MAX UINT_MAX_32_BITS
# endif
# if UINT_MAX == UINT_MAX_32_BITS
typedef unsigned int md5_uint32;
# else
# if USHRT_MAX == UINT_MAX_32_BITS
typedef unsigned short md5_uint32;
# else
# if ULONG_MAX == UINT_MAX_32_BITS
typedef unsigned long md5_uint32;
# else
/* The following line is intended to evoke an error.
Using #error is not portable enough. */
"Cannot determine unsigned 32-bit data type."
# endif
# endif
# endif
/* We have to make a guess about the integer type equivalent in size
to pointers which should always be correct. */
typedef unsigned long int md5_uintptr;
#endif
/* Structure to save state of computation between the single steps. */ /* Structure to save state of computation between the single steps. */
struct md5_ctx struct md5_ctx
@ -130,12 +92,6 @@ extern void *__md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) __THROW;
aligned for a 32 bits value. */ aligned for a 32 bits value. */
extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) __THROW; extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) __THROW;
/* Compute MD5 message digest for bytes read from STREAM. The
resulting message digest number will be written into the 16 bytes
beginning at RESBLOCK. */
extern int __md5_stream (FILE *stream, void *resblock) __THROW;
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message output yields to the wanted ASCII representation of the message

View File

@ -199,7 +199,7 @@ Romain Geissler for various fixes.
@item @item
Michael Glad for the passphrase-hashing function @code{crypt} and related 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 @item
Wolfram Gloger for contributing the memory allocation functions Wolfram Gloger for contributing the memory allocation functions

View File

@ -1,205 +1,18 @@
@node Cryptographic Functions, Debugging Support, System Configuration, Top @node Cryptographic Functions, Debugging Support, System Configuration, Top
@chapter Cryptographic Functions @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 @Theglibc{} includes only one type of special-purpose cryptographic
functions: one-way hash functions for passphrase storage, and access functions; these allow use of a source of cryptographically strong
to a cryptographic randomness source, if one is provided by the pseudorandom numbers, if such a source is provided by the operating
operating system. Programs that need general-purpose cryptography system. Programs that need general-purpose cryptography should use
should use a dedicated cryptography library, such as a dedicated cryptography library, such as
@uref{https://www.gnu.org/software/libgcrypt/,,libgcrypt}. @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 @menu
* Passphrase Storage:: One-way hashing for passphrases.
* Unpredictable Bytes:: Randomness for cryptographic purposes. * Unpredictable Bytes:: Randomness for cryptographic purposes.
@end menu @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 @node Unpredictable Bytes
@section Generating Unpredictable Bytes @section Generating Unpredictable Bytes
@cindex randomness source @cindex randomness source
@ -211,27 +24,24 @@ hashes for the same passphrase.
@cindex CSPRNG @cindex CSPRNG
@cindex DRBG @cindex DRBG
Cryptographic applications often need some random data that will be as Cryptographic applications often need random data that will be as
difficult as possible for a hostile eavesdropper to guess. For difficult as possible for a hostile eavesdropper to guess.
instance, encryption keys should be chosen at random, and the ``salt'' The pseudo-random number generators provided by @theglibc{}
strings used by @code{crypt} (@pxref{Passphrase Storage}) should also (@pxref{Pseudo-Random Numbers}) are not suitable for this purpose.
be chosen at random. They produce output that is @emph{statistically} random, but fails to
be @emph{unpredictable}. Cryptographic applications require a
Some pseudo-random number generators do not provide unpredictable-enough @dfn{cryptographic random number generator} (CRNG), also known as a
output for cryptographic applications; @pxref{Pseudo-Random Numbers}. @dfn{cryptographically strong pseudo-random number generator} (CSPRNG)
Such applications need to use a @dfn{cryptographic random number or a @dfn{deterministic random bit generator} (DRBG).
generator} (CRNG), also sometimes called a @dfn{cryptographically strong
pseudo-random number generator} (CSPRNG) or @dfn{deterministic random
bit generator} (DRBG).
Currently, @theglibc{} does not provide a cryptographic random number Currently, @theglibc{} does not provide a cryptographic random number
generator, but it does provide functions that read random data from a generator, but it does provide functions that read cryptographically
@dfn{randomness source} supplied by the operating system. The strong random data from a @dfn{randomness source} supplied by the
randomness source is a CRNG at heart, but it also continually operating system. This randomness source is a CRNG at heart, but it
``re-seeds'' itself from physical sources of randomness, such as also continually ``re-seeds'' itself from physical sources of
electronic noise and clock jitter. This means applications do not need randomness, such as electronic noise and clock jitter. This means
to do anything to ensure that the random numbers it produces are applications do not need to do anything to ensure that the random
different on each run. numbers it produces are different on each run.
The catch, however, is that these functions will only produce The catch, however, is that these functions will only produce
relatively short random strings in any one call. Often this is not a relatively short random strings in any one call. Often this is not a

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1731,8 +1731,8 @@ most systems, but on some systems a special network server gives access
to it. to it.
Historically, this database included one-way hashes of user Historically, this database included one-way hashes of user
passphrases (@pxref{Passphrase Storage}) as well as public information passphrases, as well as public information about each user
about each user (such as their user ID and full name). Many of the (such as their user ID and full name). Many of the names of
functions and data structures associated with this database, and the functions and data structures associated with this database, and the
filename @file{/etc/passwd} itself, reflect this history. However, filename @file{/etc/passwd} itself, reflect this history. However,
the information in this database is available to all users, and it is the information in this database is available to all users, and it is

View File

@ -1150,16 +1150,6 @@ ssize_t copy_file_range (int __infd, __off64_t *__pinoff,
extern int fdatasync (int __fildes); extern int fdatasync (int __fildes);
#endif /* Use POSIX199309 */ #endif /* Use POSIX199309 */
#ifdef __USE_MISC
/* One-way hash PHRASE, returning a string suitable for storage in the
user database. SALT selects the one-way function to use, and
ensures that no two users' hashes are the same, even if they use
the same passphrase. The return value points to static storage
which will be overwritten by the next call to crypt. */
extern char *crypt (const char *__key, const char *__salt)
__THROW __nonnull ((1, 2));
#endif
#ifdef __USE_XOPEN #ifdef __USE_XOPEN
/* Swab pairs bytes in the first N bytes of the area pointed to by /* Swab pairs bytes in the first N bytes of the area pointed to by
FROM and copy the result to TO. The value of TO must not be in the FROM and copy the result to TO. The value of TO must not be in the

View File

@ -465,7 +465,6 @@ class Context(object):
'--disable-profile', '--disable-profile',
'--disable-timezone-tools', '--disable-timezone-tools',
'--disable-mathvec', '--disable-mathvec',
'--disable-crypt',
'--disable-build-nscd', '--disable-build-nscd',
'--disable-nscd']}, '--disable-nscd']},
{'variant': 'no-pie', {'variant': 'no-pie',
@ -486,9 +485,7 @@ class Context(object):
{'arch': 'i586', {'arch': 'i586',
'ccopts': '-m32 -march=i586'}, 'ccopts': '-m32 -march=i586'},
{'variant': 'enable-fortify-source', {'variant': 'enable-fortify-source',
'cfg': ['--enable-fortify-source']}, 'cfg': ['--enable-fortify-source']}])
{'variant': 'enable-crypt',
'cfg': ['--enable-crypt']}])
self.add_config(arch='x86_64', self.add_config(arch='x86_64',
os_name='gnu', os_name='gnu',
gcc_cfg=['--disable-multilib']) gcc_cfg=['--disable-multilib'])

View File

@ -14,7 +14,7 @@ sed -e '/^__fpending$/d' -e '/^__flbf$/d' -e '/^__fbufsize$/d' |
sed -e '/^alloca$/d' | sed -e '/^alloca$/d' |
sort -u > DOCUMENTED sort -u > DOCUMENTED
nm --extern --define $bindir/libc.so $bindir/math/libm.so $bindir/rt/librt.so $bindir/linuxthreads/libpthread.so $bindir/dlfcn/libdl.so $bindir/crypt/libcrypt.so $bindir/login/libutil.so | nm --extern --define $bindir/libc.so $bindir/math/libm.so $bindir/rt/librt.so $bindir/linuxthreads/libpthread.so $bindir/dlfcn/libdl.so $bindir/login/libutil.so |
grep -E " [TW] ([[:alpha:]]|_[[:alpha:]])" | grep -E " [TW] ([[:alpha:]]|_[[:alpha:]])" |
sed 's/\(@.*\)//' | sed 's/\(@.*\)//' |
cut -b 12- | cut -b 12- |

View File

@ -50,9 +50,6 @@ libnss_db=2
# Version for libnsl with YP and NIS+ functions. # Version for libnsl with YP and NIS+ functions.
libnsl=1 libnsl=1
# This defines the shared library version numbers we will install.
libcrypt=1
# The gross patch for programs assuming broken locale implementations. # The gross patch for programs assuming broken locale implementations.
libBrokenLocale=1 libBrokenLocale=1

View File

@ -74,7 +74,5 @@ libc {
GLIBC_PRIVATE { GLIBC_PRIVATE {
# global variables # global variables
_itoa_lower_digits; _itoa_lower_digits;
# Used in libcrypt.
__snprintf;
} }
} }

View File

@ -1,36 +0,0 @@
/* Dummy implementation of FIPS compliance status test.
Copyright (C) 2012-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifndef _FIPS_PRIVATE_H
#define _FIPS_PRIVATE_H
#include <stdbool.h>
/* Return true if compliance with the FIPS security standards is
enabled.
This is only relevant within crypt, to tell whether MD5 and DES
algorithms should be rejected. */
static inline bool
fips_enabled_p (void)
{
return false;
}
#endif /* _FIPS_PRIVATE_H */

View File

@ -50,9 +50,7 @@ mach-before-compile:
before-compile += $(mach-before-compile) before-compile += $(mach-before-compile)
endif endif
ifeq (crypt,$(subdir)) ifeq (dlfcn,$(subdir))
LDLIBS-crypt.so += $(objdir)/mach/libmachuser.so
else ifeq (dlfcn,$(subdir))
LDLIBS-dl.so += $(objdir)/mach/libmachuser.so LDLIBS-dl.so += $(objdir)/mach/libmachuser.so
else ifeq (nis,$(subdir)) else ifeq (nis,$(subdir))
LDLIBS-nsl.so += $(objdir)/mach/libmachuser.so LDLIBS-nsl.so += $(objdir)/mach/libmachuser.so

View File

@ -1,7 +0,0 @@
GLIBC_2.2.6 crypt F
GLIBC_2.2.6 crypt_r F
GLIBC_2.2.6 encrypt F
GLIBC_2.2.6 encrypt_r F
GLIBC_2.2.6 fcrypt F
GLIBC_2.2.6 setkey F
GLIBC_2.2.6 setkey_r F

View File

@ -1,2 +0,0 @@
GLIBC_2.38 crypt F
GLIBC_2.38 crypt_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.17 crypt F
GLIBC_2.17 crypt_r F
GLIBC_2.17 encrypt F
GLIBC_2.17 encrypt_r F
GLIBC_2.17 fcrypt F
GLIBC_2.17 setkey F
GLIBC_2.17 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -10,5 +10,4 @@ libutil=1.1
libresolv=2.1 libresolv=2.1
libnsl=1.1 libnsl=1.1
libcrypt=1.1
libBrokenLocale=1.1 libBrokenLocale=1.1

View File

@ -1,2 +0,0 @@
GLIBC_2.32 crypt F
GLIBC_2.32 crypt_r F

View File

@ -17,10 +17,6 @@ endif
# Add a syscall function to each library that needs one. # Add a syscall function to each library that needs one.
ifeq ($(subdir),crypt)
libcrypt-sysdep_routines += libc-do-syscall
endif
ifeq ($(subdir),rt) ifeq ($(subdir),rt)
librt-sysdep_routines += libc-do-syscall librt-sysdep_routines += libc-do-syscall
librt-shared-only-routines += libc-do-syscall librt-shared-only-routines += libc-do-syscall

View File

@ -1,7 +0,0 @@
GLIBC_2.4 crypt F
GLIBC_2.4 crypt_r F
GLIBC_2.4 encrypt F
GLIBC_2.4 encrypt_r F
GLIBC_2.4 fcrypt F
GLIBC_2.4 setkey F
GLIBC_2.4 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.4 crypt F
GLIBC_2.4 crypt_r F
GLIBC_2.4 encrypt F
GLIBC_2.4 encrypt_r F
GLIBC_2.4 fcrypt F
GLIBC_2.4 setkey F
GLIBC_2.4 setkey_r F

View File

@ -1,2 +0,0 @@
GLIBC_2.29 crypt F
GLIBC_2.29 crypt_r F

View File

@ -1,74 +0,0 @@
/* FIPS compliance status test for GNU/Linux systems.
Copyright (C) 2012-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifndef _FIPS_PRIVATE_H
#define _FIPS_PRIVATE_H
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <not-cancel.h>
#include <stdbool.h>
/* Return true if FIPS mode is enabled. See
sysdeps/generic/fips-private.h for more information. */
static bool
fips_enabled_p (void)
{
static enum
{
FIPS_UNTESTED = 0,
FIPS_ENABLED = 1,
FIPS_DISABLED = -1,
FIPS_TEST_FAILED = -2
} checked;
if (checked == FIPS_UNTESTED)
{
int fd = __open_nocancel ("/proc/sys/crypto/fips_enabled", O_RDONLY);
if (fd != -1)
{
/* This is more than enough, the file contains a single integer. */
char buf[32];
ssize_t n;
n = TEMP_FAILURE_RETRY (__read_nocancel (fd, buf, sizeof (buf) - 1));
__close_nocancel_nostatus (fd);
if (n > 0)
{
/* Terminate the string. */
buf[n] = '\0';
char *endp;
long int res = strtol (buf, &endp, 10);
if (endp != buf && (*endp == '\0' || *endp == '\n'))
checked = (res > 0) ? FIPS_ENABLED : FIPS_DISABLED;
}
}
if (checked == FIPS_UNTESTED)
checked = FIPS_TEST_FAILED;
}
return checked == FIPS_ENABLED;
}
#endif /* _FIPS_PRIVATE_H */

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,2 +0,0 @@
GLIBC_2.36 crypt F
GLIBC_2.36 crypt_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.4 crypt F
GLIBC_2.4 crypt_r F
GLIBC_2.4 encrypt F
GLIBC_2.4 encrypt_r F
GLIBC_2.4 fcrypt F
GLIBC_2.4 setkey F
GLIBC_2.4 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.18 crypt F
GLIBC_2.18 crypt_r F
GLIBC_2.18 encrypt F
GLIBC_2.18 encrypt_r F
GLIBC_2.18 fcrypt F
GLIBC_2.18 setkey F
GLIBC_2.18 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.18 crypt F
GLIBC_2.18 crypt_r F
GLIBC_2.18 encrypt F
GLIBC_2.18 encrypt_r F
GLIBC_2.18 fcrypt F
GLIBC_2.18 setkey F
GLIBC_2.18 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.21 crypt F
GLIBC_2.21 crypt_r F
GLIBC_2.21 encrypt F
GLIBC_2.21 encrypt_r F
GLIBC_2.21 fcrypt F
GLIBC_2.21 setkey F
GLIBC_2.21 setkey_r F

View File

@ -1,2 +0,0 @@
GLIBC_2.35 crypt F
GLIBC_2.35 crypt_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.3 crypt F
GLIBC_2.3 crypt_r F
GLIBC_2.3 encrypt F
GLIBC_2.3 encrypt_r F
GLIBC_2.3 fcrypt F
GLIBC_2.3 setkey F
GLIBC_2.3 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.17 crypt F
GLIBC_2.17 crypt_r F
GLIBC_2.17 encrypt F
GLIBC_2.17 encrypt_r F
GLIBC_2.17 fcrypt F
GLIBC_2.17 setkey F
GLIBC_2.17 setkey_r F

View File

@ -1,2 +0,0 @@
GLIBC_2.33 crypt F
GLIBC_2.33 crypt_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.27 crypt F
GLIBC_2.27 crypt_r F
GLIBC_2.27 encrypt F
GLIBC_2.27 encrypt_r F
GLIBC_2.27 fcrypt F
GLIBC_2.27 setkey F
GLIBC_2.27 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.2 crypt F
GLIBC_2.2 crypt_r F
GLIBC_2.2 encrypt F
GLIBC_2.2 encrypt_r F
GLIBC_2.2 fcrypt F
GLIBC_2.2 setkey F
GLIBC_2.2 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.0 crypt F
GLIBC_2.0 crypt_r F
GLIBC_2.0 encrypt F
GLIBC_2.0 encrypt_r F
GLIBC_2.0 fcrypt F
GLIBC_2.0 setkey F
GLIBC_2.0 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.2.5 crypt F
GLIBC_2.2.5 crypt_r F
GLIBC_2.2.5 encrypt F
GLIBC_2.2.5 encrypt_r F
GLIBC_2.2.5 fcrypt F
GLIBC_2.2.5 setkey F
GLIBC_2.2.5 setkey_r F

View File

@ -1,7 +0,0 @@
GLIBC_2.16 crypt F
GLIBC_2.16 crypt_r F
GLIBC_2.16 encrypt F
GLIBC_2.16 encrypt_r F
GLIBC_2.16 fcrypt F
GLIBC_2.16 setkey F
GLIBC_2.16 setkey_r F