* configure.in: Recognize --enable-nss-crypt.

* config.make.in: Add nss-crypt entry.
	* crypt/Makefile: If nss-crypt==yes, don't build md5.c, sha256.c,
	sha512.c.  Don't run md5test, sha256test, sha512test.  Pass -DUSE_NSS
	and include path for NSS directory to compiler for md5-crypt,
	sha256-crypt, sha512-crypt.  Link libcrypt.so with -lfreebl3.
	* crypt/md5-crypt.c: If USE_NSS is defined, don't use local hash
	function implementation, use NSS.  Introduce wrappers around the
	hash function calls.  Little code size optimization.
	* crypt/sha256-crypt.c: Likewise.
	* crypt/sha512-crypt.c: Likewise.
	* scripts/check-local-headers.sh: Ignore nss3 directory.

	* configure.in: Rename pic_default to libc_cv_pic_default.
	* config.make.in: Likewise.
This commit is contained in:
Ulrich Drepper 2009-04-02 17:00:46 +00:00
parent 900d7961d4
commit ff886b82a2
8 changed files with 3213 additions and 2028 deletions

View File

@ -1,3 +1,21 @@
2009-04-02 Ulrich Drepper <drepper@redhat.com>
* configure.in: Recognize --enable-nss-crypt.
* config.make.in: Add nss-crypt entry.
* crypt/Makefile: If nss-crypt==yes, don't build md5.c, sha256.c,
sha512.c. Don't run md5test, sha256test, sha512test. Pass -DUSE_NSS
and include path for NSS directory to compiler for md5-crypt,
sha256-crypt, sha512-crypt. Link libcrypt.so with -lfreebl3.
* crypt/md5-crypt.c: If USE_NSS is defined, don't use local hash
function implementation, use NSS. Introduce wrappers around the
hash function calls. Little code size optimization.
* crypt/sha256-crypt.c: Likewise.
* crypt/sha512-crypt.c: Likewise.
* scripts/check-local-headers.sh: Ignore nss3 directory.
* configure.in: Rename pic_default to libc_cv_pic_default.
* config.make.in: Likewise.
2009-04-01 Roland McGrath <roland@redhat.com>
* elf/elf.h (R_SPARC_GLOB_JMP): New macro.

4720
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -272,6 +272,41 @@ AC_ARG_ENABLE([experimental-malloc],
[])
AC_SUBST(experimental_malloc)
AC_ARG_ENABLE([nss-crypt],
AC_HELP_STRING([--enable-nss-crypt],
[enable libcrypt to use nss]),
[nss_crypt=$enableval],
[nss_crypt=no])
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
old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $nss_includes"
AC_COMPILE_IFELSE([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"
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]))
CFLAGS="$old_CFLAGS"
LIBS="$old_LIBS"
else
libc_cv_nss_crypt=no
fi
AC_SUBST(libc_cv_nss_crypt)
AC_CANONICAL_HOST
# The way shlib-versions is used to generate soversions.mk uses a
@ -2241,18 +2276,18 @@ if test $shared = default; then
shared=$elf
fi
AC_CACHE_CHECK([whether -fPIC is default], pic_default,
[pic_default=yes
AC_CACHE_CHECK([whether -fPIC is default], libc_cv_pic_default,
[libc_cv_pic_default=yes
cat > conftest.c <<EOF
#if defined __PIC__ || defined __pic__ || defined PIC || defined pic
# error PIC is default.
#endif
EOF
if eval "${CC-cc} -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then
pic_default=no
libc_cv_pic_default=no
fi
rm -f conftest.*])
AC_SUBST(pic_default)
AC_SUBST(libc_cv_pic_default)
AC_SUBST(profile)
AC_SUBST(omitfp)

View File

@ -1,4 +1,4 @@
# Copyright (C) 1996, 2000, 2001, 2007 Free Software Foundation, Inc.
# Copyright (C) 1996, 2000, 2001, 2007, 2009 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
@ -26,10 +26,10 @@ headers := crypt.h
extra-libs := libcrypt
extra-libs-others := $(extra-libs)
libcrypt-routines := crypt-entry md5-crypt md5 sha256-crypt sha256 \
sha512-crypt sha512 crypt crypt_util
libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
crypt_util
tests := cert md5test md5c-test sha256test sha256c-test sha512test sha512c-test
tests := cert md5c-test sha256c-test sha512c-test
distribute := ufc-crypt.h crypt-private.h ufc.c speeds.c README.ufc-crypt \
Banner md5.h sha256.h sha512.h
@ -40,9 +40,20 @@ ifeq ($(crypt-in-libc),yes)
routines += $(libcrypt-routines)
endif
ifeq ($(nss-crypt),yes)
CPPFLAGS-sha256-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
CPPFLAGS-sha512-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
CPPFLAGS-md5-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
$(objpfx)libcrypt.so: -lfreebl3
else
libcrypt-routines += md5 sha256 sha512
tests += md5test sha256test sha512test
$(objpfx)md5test: $(objpfx)md5.o
$(objpfx)sha256test: $(objpfx)sha256.o
$(objpfx)sha512test: $(objpfx)sha512.o
endif
include ../Rules

View File

@ -1,6 +1,6 @@
/* One way encryption based on MD5 sum.
Compatible with the behavior of MD5 crypt introduced in FreeBSD 2.0.
Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2004
Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2004, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@ -29,6 +29,52 @@
#include "md5.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. */
@ -56,8 +102,6 @@ __md5_crypt_r (key, salt, buffer, buflen)
{
unsigned char alt_result[16]
__attribute__ ((__aligned__ (__alignof__ (md5_uint32))));
struct md5_ctx ctx;
struct md5_ctx alt_ctx;
size_t salt_len;
size_t key_len;
size_t cnt;
@ -94,43 +138,56 @@ __md5_crypt_r (key, salt, buffer, buflen)
assert ((salt - (char *) 0) % __alignof__ (md5_uint32) == 0);
}
#ifdef USE_NSS
/* Initialize libfreebl3. */
NSSLOWInitContext *nss_ictx = NSSLOW_Init ();
if (nss_ictx == NULL)
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);
md5_init_ctx (&ctx, nss_ctx);
/* Add the key string. */
__md5_process_bytes (key, key_len, &ctx);
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);
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);
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);
md5_init_ctx (&alt_ctx, nss_alt_ctx);
/* Add key. */
__md5_process_bytes (key, key_len, &alt_ctx);
md5_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Add salt. */
__md5_process_bytes (salt, salt_len, &alt_ctx);
md5_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
/* Add key again. */
__md5_process_bytes (key, key_len, &alt_ctx);
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, alt_result);
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);
__md5_process_bytes (alt_result, cnt, &ctx);
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';
@ -140,11 +197,12 @@ __md5_crypt_r (key, salt, buffer, buflen)
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 char *) alt_result : key, 1,
&ctx);
md5_process_bytes ((cnt & 1) != 0
? (const void *) alt_result : (const void *) key, 1,
&ctx, nss_ctx);
/* Create intermediate result. */
__md5_finish_ctx (&ctx, alt_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
@ -152,32 +210,37 @@ __md5_crypt_r (key, salt, buffer, buflen)
for (cnt = 0; cnt < 1000; ++cnt)
{
/* New context. */
__md5_init_ctx (&ctx);
md5_init_ctx (&ctx, nss_ctx);
/* Add key or last result. */
if ((cnt & 1) != 0)
__md5_process_bytes (key, key_len, &ctx);
md5_process_bytes (key, key_len, &ctx, nss_ctx);
else
__md5_process_bytes (alt_result, 16, &ctx);
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);
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);
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);
md5_process_bytes (alt_result, 16, &ctx, nss_ctx);
else
__md5_process_bytes (key, key_len, &ctx);
md5_process_bytes (key, key_len, &ctx, nss_ctx);
/* Create intermediate result. */
__md5_finish_ctx (&ctx, alt_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));
@ -192,18 +255,17 @@ __md5_crypt_r (key, salt, buffer, buflen)
--buflen;
}
#define b64_from_24bit(B2, B1, B0, N) \
do { \
unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
int n = (N); \
while (n-- > 0 && buflen > 0) \
{ \
*cp++ = b64t[w & 0x3f]; \
--buflen; \
w >>= 6; \
} \
} while (0)
void b64_from_24bit (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;
}
}
b64_from_24bit (alt_result[0], alt_result[6], alt_result[12], 4);
b64_from_24bit (alt_result[1], alt_result[7], alt_result[13], 4);
@ -223,10 +285,12 @@ __md5_crypt_r (key, salt, buffer, buflen)
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);
memset (&ctx, '\0', sizeof (ctx));
memset (&alt_ctx, '\0', sizeof (alt_ctx));
#endif
if (copied_key != NULL)
memset (copied_key, '\0', key_len);
if (copied_salt != NULL)

View File

@ -1,5 +1,5 @@
/* One way encryption based on SHA256 sum.
Copyright (C) 2007 Free Software Foundation, Inc.
Copyright (C) 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
@ -28,6 +28,52 @@
#include "sha256.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$";
@ -66,8 +112,6 @@ __sha256_crypt_r (key, salt, buffer, buflen)
__attribute__ ((__aligned__ (__alignof__ (uint32_t))));
unsigned char temp_result[32]
__attribute__ ((__aligned__ (__alignof__ (uint32_t))));
struct sha256_ctx ctx;
struct sha256_ctx alt_ctx;
size_t salt_len;
size_t key_len;
size_t cnt;
@ -123,59 +167,71 @@ __sha256_crypt_r (key, salt, buffer, buflen)
assert ((salt - (char *) 0) % __alignof__ (uint32_t) == 0);
}
#ifdef USE_NSS
/* Initialize libfreebl3. */
NSSLOWInitContext *nss_ictx = NSSLOW_Init ();
if (nss_ictx == NULL)
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);
sha256_init_ctx (&ctx, nss_ctx);
/* Add the key string. */
__sha256_process_bytes (key, key_len, &ctx);
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);
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);
sha256_init_ctx (&alt_ctx, nss_alt_ctx);
/* Add key. */
__sha256_process_bytes (key, key_len, &alt_ctx);
sha256_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Add salt. */
__sha256_process_bytes (salt, salt_len, &alt_ctx);
sha256_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
/* Add key again. */
__sha256_process_bytes (key, key_len, &alt_ctx);
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, alt_result);
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);
__sha256_process_bytes (alt_result, cnt, &ctx);
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);
sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
else
__sha256_process_bytes (key, key_len, &ctx);
sha256_process_bytes (key, key_len, &ctx, nss_ctx);
/* Create intermediate result. */
__sha256_finish_ctx (&ctx, alt_result);
sha256_finish_ctx (&ctx, nss_ctx, alt_result);
/* Start computation of P byte sequence. */
__sha256_init_ctx (&alt_ctx);
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);
sha256_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Finish the digest. */
__sha256_finish_ctx (&alt_ctx, temp_result);
sha256_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
/* Create byte sequence P. */
cp = p_bytes = alloca (key_len);
@ -184,14 +240,14 @@ __sha256_crypt_r (key, salt, buffer, buflen)
memcpy (cp, temp_result, cnt);
/* Start computation of S byte sequence. */
__sha256_init_ctx (&alt_ctx);
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);
sha256_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
/* Finish the digest. */
__sha256_finish_ctx (&alt_ctx, temp_result);
sha256_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
/* Create byte sequence S. */
cp = s_bytes = alloca (salt_len);
@ -204,32 +260,37 @@ __sha256_crypt_r (key, salt, buffer, buflen)
for (cnt = 0; cnt < rounds; ++cnt)
{
/* New context. */
__sha256_init_ctx (&ctx);
sha256_init_ctx (&ctx, nss_ctx);
/* Add key or last result. */
if ((cnt & 1) != 0)
__sha256_process_bytes (p_bytes, key_len, &ctx);
sha256_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
else
__sha256_process_bytes (alt_result, 32, &ctx);
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);
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);
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);
sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
else
__sha256_process_bytes (p_bytes, key_len, &ctx);
sha256_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
/* Create intermediate result. */
__sha256_finish_ctx (&ctx, alt_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));
@ -252,17 +313,17 @@ __sha256_crypt_r (key, salt, buffer, buflen)
--buflen;
}
#define b64_from_24bit(B2, B1, B0, N) \
do { \
unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
int n = (N); \
while (n-- > 0 && buflen > 0) \
{ \
*cp++ = b64t[w & 0x3f]; \
--buflen; \
w >>= 6; \
} \
} while (0)
void b64_from_24bit (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;
}
}
b64_from_24bit (alt_result[0], alt_result[10], alt_result[20], 4);
b64_from_24bit (alt_result[21], alt_result[1], alt_result[11], 4);
@ -287,13 +348,15 @@ __sha256_crypt_r (key, salt, buffer, buflen)
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);
memset (&ctx, '\0', sizeof (ctx));
memset (&alt_ctx, '\0', sizeof (alt_ctx));
#endif
memset (temp_result, '\0', sizeof (temp_result));
memset (p_bytes, '\0', key_len);
memset (s_bytes, '\0', salt_len);
memset (&ctx, '\0', sizeof (ctx));
memset (&alt_ctx, '\0', sizeof (alt_ctx));
if (copied_key != NULL)
memset (copied_key, '\0', key_len);
if (copied_salt != NULL)

View File

@ -1,5 +1,5 @@
/* One way encryption based on SHA512 sum.
Copyright (C) 2007 Free Software Foundation, Inc.
Copyright (C) 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
@ -28,6 +28,52 @@
#include "sha512.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$";
@ -66,8 +112,6 @@ __sha512_crypt_r (key, salt, buffer, buflen)
__attribute__ ((__aligned__ (__alignof__ (uint64_t))));
unsigned char temp_result[64]
__attribute__ ((__aligned__ (__alignof__ (uint64_t))));
struct sha512_ctx ctx;
struct sha512_ctx alt_ctx;
size_t salt_len;
size_t key_len;
size_t cnt;
@ -123,59 +167,71 @@ __sha512_crypt_r (key, salt, buffer, buflen)
assert ((salt - (char *) 0) % __alignof__ (uint64_t) == 0);
}
#ifdef USE_NSS
/* Initialize libfreebl3. */
NSSLOWInitContext *nss_ictx = NSSLOW_Init ();
if (nss_ictx == NULL)
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);
sha512_init_ctx (&ctx, nss_ctx);
/* Add the key string. */
__sha512_process_bytes (key, key_len, &ctx);
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);
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);
sha512_init_ctx (&alt_ctx, nss_alt_ctx);
/* Add key. */
__sha512_process_bytes (key, key_len, &alt_ctx);
sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Add salt. */
__sha512_process_bytes (salt, salt_len, &alt_ctx);
sha512_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
/* Add key again. */
__sha512_process_bytes (key, key_len, &alt_ctx);
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, alt_result);
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);
__sha512_process_bytes (alt_result, cnt, &ctx);
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);
sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
else
__sha512_process_bytes (key, key_len, &ctx);
sha512_process_bytes (key, key_len, &ctx, nss_ctx);
/* Create intermediate result. */
__sha512_finish_ctx (&ctx, alt_result);
sha512_finish_ctx (&ctx, nss_ctx, alt_result);
/* Start computation of P byte sequence. */
__sha512_init_ctx (&alt_ctx);
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);
sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
/* Finish the digest. */
__sha512_finish_ctx (&alt_ctx, temp_result);
sha512_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
/* Create byte sequence P. */
cp = p_bytes = alloca (key_len);
@ -184,14 +240,14 @@ __sha512_crypt_r (key, salt, buffer, buflen)
memcpy (cp, temp_result, cnt);
/* Start computation of S byte sequence. */
__sha512_init_ctx (&alt_ctx);
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);
sha512_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
/* Finish the digest. */
__sha512_finish_ctx (&alt_ctx, temp_result);
sha512_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
/* Create byte sequence S. */
cp = s_bytes = alloca (salt_len);
@ -204,32 +260,37 @@ __sha512_crypt_r (key, salt, buffer, buflen)
for (cnt = 0; cnt < rounds; ++cnt)
{
/* New context. */
__sha512_init_ctx (&ctx);
sha512_init_ctx (&ctx, nss_ctx);
/* Add key or last result. */
if ((cnt & 1) != 0)
__sha512_process_bytes (p_bytes, key_len, &ctx);
sha512_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
else
__sha512_process_bytes (alt_result, 64, &ctx);
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);
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);
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);
sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
else
__sha512_process_bytes (p_bytes, key_len, &ctx);
sha512_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
/* Create intermediate result. */
__sha512_finish_ctx (&ctx, alt_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));
@ -252,17 +313,17 @@ __sha512_crypt_r (key, salt, buffer, buflen)
--buflen;
}
#define b64_from_24bit(B2, B1, B0, N) \
do { \
unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
int n = (N); \
while (n-- > 0 && buflen > 0) \
{ \
*cp++ = b64t[w & 0x3f]; \
--buflen; \
w >>= 6; \
} \
} while (0)
void b64_from_24bit (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;
}
}
b64_from_24bit (alt_result[0], alt_result[21], alt_result[42], 4);
b64_from_24bit (alt_result[22], alt_result[43], alt_result[1], 4);
@ -299,13 +360,15 @@ __sha512_crypt_r (key, salt, buffer, buflen)
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);
memset (&ctx, '\0', sizeof (ctx));
memset (&alt_ctx, '\0', sizeof (alt_ctx));
#endif
memset (temp_result, '\0', sizeof (temp_result));
memset (p_bytes, '\0', key_len);
memset (s_bytes, '\0', salt_len);
memset (&ctx, '\0', sizeof (ctx));
memset (&alt_ctx, '\0', sizeof (alt_ctx));
if (copied_key != NULL)
memset (copied_key, '\0', key_len);
if (copied_salt != NULL)

View File

@ -1,5 +1,5 @@
#! /bin/bash
# Copyright (C) 2005, 2007 Free Software Foundation, Inc.
# Copyright (C) 2005, 2007, 2009 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
@ -31,7 +31,8 @@ fgrep -v "$includedir/asm" |
fgrep -v "$includedir/linux" |
fgrep -v "$includedir/selinux" |
fgrep -v "$includedir/sys/capability.h" |
fgrep -v "$includedir/gd"; then
fgrep -v "$includedir/gd" |
fgrep -v "$includedir/nss3"; then
# If we found a match something is wrong.
exit 1
fi