diff --git a/crypt_blowfish-1.1-sha.diff b/crypt_blowfish-1.1-sha.diff deleted file mode 100644 index f24d94c..0000000 --- a/crypt_blowfish-1.1-sha.diff +++ /dev/null @@ -1,213 +0,0 @@ -From 22a0cc20633a4ddd61233410563c9fabe6b515ed Mon Sep 17 00:00:00 2001 -From: Ludwig Nussel -Date: Tue, 5 Jul 2011 17:25:12 +0200 -Subject: [PATCH crypt_blowfish 1/2] support for sha256 and sha512 - ---- - crypt_gensalt.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - wrapper.c | 28 +++++++++++++ - 2 files changed, 147 insertions(+), 0 deletions(-) - -diff --git a/crypt_gensalt.c b/crypt_gensalt.c -index 43b0f6c..4600e30 100644 ---- a/crypt_gensalt.c -+++ b/crypt_gensalt.c -@@ -7,6 +7,11 @@ - * entirely in crypt_blowfish.c. - */ - -+/* asprintf&free */ -+#define _GNU_SOURCE -+#include -+#include -+ - #include - - #include -@@ -105,3 +110,117 @@ char *_crypt_gensalt_md5_rn(unsigned long count, - - return output; - } -+ -+char *_crypt_gensalt_sha256_rn (unsigned long count, -+ const char *input, int size, char *output, int output_size) -+{ -+ unsigned long value; -+ char *buf; -+ char buf2[12]; -+ -+ if (count > 0) { -+ if (asprintf (&buf, "$5$rounds=%ld$", count) < 0) { -+ if (output_size > 0) -+ output[0] = '\0'; -+ errno = ENOMEM; -+ return NULL; -+ } -+ } else { -+ if (asprintf (&buf, "$5$") < 0) { -+ if (output_size > 0) -+ output[0] = '\0'; -+ errno = ENOMEM; -+ return NULL; -+ } -+ } -+ -+ if (size < 3 || output_size < (int)strlen (buf) + 4 + 1) { -+ free (buf); -+ if (output_size > 0) -+ output[0] = '\0'; -+ errno = ERANGE; -+ return NULL; -+ } -+ -+ value = (unsigned long)(unsigned char)input[0] | -+ ((unsigned long)(unsigned char)input[1] << 8) | -+ ((unsigned long)(unsigned char)input[2] << 16); -+ buf2[0] = _crypt_itoa64[value & 0x3f]; -+ buf2[1] = _crypt_itoa64[(value >> 6) & 0x3f]; -+ buf2[2] = _crypt_itoa64[(value >> 12) & 0x3f]; -+ buf2[3] = _crypt_itoa64[(value >> 18) & 0x3f]; -+ buf2[4] = '\0'; -+ -+ if (size >= 6 && output_size >= (int)strlen (buf) + 4 + 4 + 1) { -+ value = (unsigned long)(unsigned char)input[3] | -+ ((unsigned long)(unsigned char)input[4] << 8) | -+ ((unsigned long)(unsigned char)input[5] << 16); -+ buf2[4] = _crypt_itoa64[value & 0x3f]; -+ buf2[5] = _crypt_itoa64[(value >> 6) & 0x3f]; -+ buf2[6] = _crypt_itoa64[(value >> 12) & 0x3f]; -+ buf2[7] = _crypt_itoa64[(value >> 18) & 0x3f]; -+ buf2[8] = '\0'; -+ } -+ -+ snprintf (output, output_size, "%s%s", buf, buf2); -+ free (buf); -+ -+ return output; -+} -+ -+char *_crypt_gensalt_sha512_rn (unsigned long count, -+ const char *input, int size, char *output, int output_size) -+{ -+ unsigned long value; -+ char *buf; -+ char buf2[12]; -+ -+ if (count > 0) { -+ if (asprintf (&buf, "$6$rounds=%ld$", count) < 0) { -+ if (output_size > 0) -+ output[0] = '\0'; -+ errno = ENOMEM; -+ return NULL; -+ } -+ } else { -+ if (asprintf (&buf, "$6$") < 0) { -+ if (output_size > 0) -+ output[0] = '\0'; -+ errno = ENOMEM; -+ return NULL; -+ } -+ } -+ -+ if (size < 3 || output_size < (int)strlen (buf) + 4 + 1) { -+ free (buf); -+ if (output_size > 0) -+ output[0] = '\0'; -+ __set_errno(ERANGE); -+ return NULL; -+ } -+ -+ value = (unsigned long)(unsigned char)input[0] | -+ ((unsigned long)(unsigned char)input[1] << 8) | -+ ((unsigned long)(unsigned char)input[2] << 16); -+ buf2[0] = _crypt_itoa64[value & 0x3f]; -+ buf2[1] = _crypt_itoa64[(value >> 6) & 0x3f]; -+ buf2[2] = _crypt_itoa64[(value >> 12) & 0x3f]; -+ buf2[3] = _crypt_itoa64[(value >> 18) & 0x3f]; -+ buf2[4] = '\0'; -+ -+ if (size >= 6 && output_size >= (int)strlen (buf) + 4 + 4 + 1) { -+ value = (unsigned long)(unsigned char)input[3] | -+ ((unsigned long)(unsigned char)input[4] << 8) | -+ ((unsigned long)(unsigned char)input[5] << 16); -+ buf2[4] = _crypt_itoa64[value & 0x3f]; -+ buf2[5] = _crypt_itoa64[(value >> 6) & 0x3f]; -+ buf2[6] = _crypt_itoa64[(value >> 12) & 0x3f]; -+ buf2[7] = _crypt_itoa64[(value >> 18) & 0x3f]; -+ buf2[8] = '\0'; -+ } -+ -+ snprintf (output, output_size, "%s%s", buf, buf2); -+ free (buf); -+ -+ return output; -+} -diff --git a/wrapper.c b/wrapper.c -index af441bc..07772bc 100644 ---- a/wrapper.c -+++ b/wrapper.c -@@ -33,12 +33,20 @@ - - #include "crypt_blowfish.h" - #include "crypt_gensalt.h" -+extern char *_crypt_gensalt_sha256_rn(unsigned long count, -+ const char *input, int size, char *output, int output_size); -+extern char *_crypt_gensalt_sha512_rn(unsigned long count, -+ const char *input, int size, char *output, int output_size); - - #if defined(__GLIBC__) && defined(_LIBC) - /* crypt.h from glibc-crypt-2.1 will define struct crypt_data for us */ - #include "crypt.h" - extern char *__md5_crypt_r(const char *key, const char *salt, - char *buffer, int buflen); -+extern char *__sha256_crypt_r (const char *key, const char *salt, -+ char *buffer, int buflen); -+extern char *__sha512_crypt_r (const char *key, const char *salt, -+ char *buffer, int buflen); - /* crypt-entry.c needs to be patched to define __des_crypt_r rather than - * __crypt_r, and not define crypt_r and crypt at all */ - extern char *__des_crypt_r(const char *key, const char *salt, -@@ -101,6 +109,10 @@ static char *_crypt_retval_magic(char *retval, const char *setting, - char *__crypt_rn(__const char *key, __const char *setting, - void *data, int size) - { -+ if (setting[0] == '$' && setting[1] == '6') -+ return __sha512_crypt_r(key, setting, (char *)data, size); -+ if (setting[0] == '$' && setting[1] == '5') -+ return __sha256_crypt_r(key, setting, (char *)data, size); - if (setting[0] == '$' && setting[1] == '2') - return _crypt_blowfish_rn(key, setting, (char *)data, size); - if (setting[0] == '$' && setting[1] == '1') -@@ -118,6 +130,16 @@ char *__crypt_rn(__const char *key, __const char *setting, - char *__crypt_ra(__const char *key, __const char *setting, - void **data, int *size) - { -+ if (setting[0] == '$' && setting[1] == '6') { -+ if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) -+ return NULL; -+ return __sha512_crypt_r(key, setting, (char *)*data, *size); -+ } -+ if (setting[0] == '$' && setting[1] == '5') { -+ if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) -+ return NULL; -+ return __sha256_crypt_r(key, setting, (char *)*data, *size); -+ } - if (setting[0] == '$' && setting[1] == '2') { - if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) - return NULL; -@@ -199,6 +221,12 @@ char *__crypt_gensalt_rn(const char *prefix, unsigned long count, - return NULL; - } - -+ if (!strncmp(prefix, "$6$", 3)) -+ use = _crypt_gensalt_sha512_rn; -+ else -+ if (!strncmp(prefix, "$5$", 3)) -+ use = _crypt_gensalt_sha256_rn; -+ else - if (!strncmp(prefix, "$2a$", 4) || !strncmp(prefix, "$2y$", 4)) - use = _crypt_gensalt_blowfish_rn; - else --- -1.7.3.4 - diff --git a/crypt_blowfish-1.2-sha.diff b/crypt_blowfish-1.2-sha.diff new file mode 100644 index 0000000..546acec --- /dev/null +++ b/crypt_blowfish-1.2-sha.diff @@ -0,0 +1,173 @@ +From 1c581a8364ab18a6938f3153d7bea793d06a4652 Mon Sep 17 00:00:00 2001 +From: Ludwig Nussel +Date: Thu, 25 Aug 2011 14:00:38 +0200 +Subject: [PATCH crypt_blowfish] support for sha256 and sha512 + +--- + crypt.3 | 14 +++++++++++++ + crypt_gensalt.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + wrapper.c | 23 +++++++++++++++++++++ + 3 files changed, 95 insertions(+), 0 deletions(-) + +diff --git a/crypt.3 b/crypt.3 +index e2f25bd..40a3538 100644 +--- a/crypt.3 ++++ b/crypt.3 +@@ -399,6 +399,20 @@ too low for the currently available hardware. + .hash "$1$" "\e$1\e$[^$]{1,8}\e$[./0-9A-Za-z]{22}" unlimited 8 "" 128 "6 to 48" 1000 + .PP + .ti -2 ++.B SHA256 based ++.br ++This is Ulrich Drepper's SHA256-based password hashing method originally ++developed for Linux. ++.hash "$5$" "\e$5\e$(rounds=[0-9]{1,9}\e$)?([./0-9A-Za-z]{1,16})?\e$[./0-9A-Za-z]{43}" unlimited 8 "" 256 "0 to 96" "1000 to 999999999 (default 5000)" ++.PP ++.ti -2 ++.B SHA512 based ++.br ++This is Ulrich Drepper's SHA512-based password hashing method originally ++developed for Linux. ++.hash "$6$" "\e$6\e$(rounds=[0-9]{1,9}\e$)?([./0-9A-Za-z]{1,16})?\e$[./0-9A-Za-z]{86}" unlimited 8 "" 512 "0 to 96" "1000 to 999999999 (default 5000)" ++.PP ++.ti -2 + .BR "OpenBSD-style Blowfish-based" " (" bcrypt ) + .br + .B bcrypt +diff --git a/crypt_gensalt.c b/crypt_gensalt.c +index 73c15a1..5cf9812 100644 +--- a/crypt_gensalt.c ++++ b/crypt_gensalt.c +@@ -19,6 +19,7 @@ + */ + + #include ++#include + + #include + #ifndef __set_errno +@@ -122,3 +123,60 @@ char *_crypt_gensalt_md5_rn(const char *prefix, unsigned long count, + + return output; + } ++ ++#define SHA2_SALT_LEN_MAX 16 ++#define SHA2_ROUNDS_MIN 1000 ++#define SHA2_ROUNDS_MAX 999999999 ++char *_crypt_gensalt_sha2_rn (const char *prefix, unsigned long count, ++ const char *input, int size, char *output, int output_size) ++ ++{ ++ char *o = output; ++ const char *i = input; ++ unsigned needed = 3 + MIN(size/3*4, SHA2_SALT_LEN_MAX) + 1; ++ ++ if (size < 3 || output_size < needed) ++ goto error; ++ ++ size = MIN(size, SHA2_SALT_LEN_MAX/4*3); ++ ++ o[0] = prefix[0]; ++ o[1] = prefix[1]; ++ o[2] = prefix[2]; ++ o += 3; ++ ++ if (count) { ++ count = MAX(SHA2_ROUNDS_MIN, MIN(count, SHA2_ROUNDS_MAX)); ++ int n = snprintf (o, output_size-3, "rounds=%ld$", count); ++ if (n < 0 || n >= output_size-3) ++ goto error; ++ needed += n; ++ o += n; ++ } ++ ++ if (output_size < needed) ++ goto error; ++ ++ while (size >= 3) { ++ unsigned long value = ++ (unsigned long)(unsigned char)i[0] | ++ ((unsigned long)(unsigned char)i[1] << 8) | ++ ((unsigned long)(unsigned char)i[2] << 16); ++ o[0] = _crypt_itoa64[value & 0x3f]; ++ o[1] = _crypt_itoa64[(value >> 6) & 0x3f]; ++ o[2] = _crypt_itoa64[(value >> 12) & 0x3f]; ++ o[3] = _crypt_itoa64[(value >> 18) & 0x3f]; ++ size -= 3; ++ i += 3; ++ o += 3; ++ } ++ o[0] = '\0'; ++ ++ return output; ++ ++error: ++ if (output_size > 0) ++ output[0] = '\0'; ++ errno = ENOMEM; ++ return NULL; ++} +diff --git a/wrapper.c b/wrapper.c +index 344053b..070d91d 100644 +--- a/wrapper.c ++++ b/wrapper.c +@@ -44,12 +44,18 @@ + + #include "crypt_blowfish.h" + #include "crypt_gensalt.h" ++extern char *_crypt_gensalt_sha2_rn(const char *prefix, unsigned long count, ++ const char *input, int size, char *output, int output_size); + + #if defined(__GLIBC__) && defined(_LIBC) + /* crypt.h from glibc-crypt-2.1 will define struct crypt_data for us */ + #include "crypt.h" + extern char *__md5_crypt_r(const char *key, const char *salt, + char *buffer, int buflen); ++extern char *__sha256_crypt_r (const char *key, const char *salt, ++ char *buffer, int buflen); ++extern char *__sha512_crypt_r (const char *key, const char *salt, ++ char *buffer, int buflen); + /* crypt-entry.c needs to be patched to define __des_crypt_r rather than + * __crypt_r, and not define crypt_r and crypt at all */ + extern char *__des_crypt_r(const char *key, const char *salt, +@@ -112,6 +118,10 @@ static char *_crypt_retval_magic(char *retval, const char *setting, + char *__crypt_rn(__const char *key, __const char *setting, + void *data, int size) + { ++ if (setting[0] == '$' && setting[1] == '6') ++ return __sha512_crypt_r(key, setting, (char *)data, size); ++ if (setting[0] == '$' && setting[1] == '5') ++ return __sha256_crypt_r(key, setting, (char *)data, size); + if (setting[0] == '$' && setting[1] == '2') + return _crypt_blowfish_rn(key, setting, (char *)data, size); + if (setting[0] == '$' && setting[1] == '1') +@@ -129,6 +139,16 @@ char *__crypt_rn(__const char *key, __const char *setting, + char *__crypt_ra(__const char *key, __const char *setting, + void **data, int *size) + { ++ if (setting[0] == '$' && setting[1] == '6') { ++ if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) ++ return NULL; ++ return __sha512_crypt_r(key, setting, (char *)*data, *size); ++ } ++ if (setting[0] == '$' && setting[1] == '5') { ++ if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) ++ return NULL; ++ return __sha256_crypt_r(key, setting, (char *)*data, *size); ++ } + if (setting[0] == '$' && setting[1] == '2') { + if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) + return NULL; +@@ -210,6 +230,9 @@ char *__crypt_gensalt_rn(const char *prefix, unsigned long count, + return NULL; + } + ++ if (!strncmp(prefix, "$5$", 3) || !strncmp(prefix, "$6$", 3)) ++ use = _crypt_gensalt_sha2_rn; ++ else + if (!strncmp(prefix, "$2a$", 4) || !strncmp(prefix, "$2y$", 4)) + use = _crypt_gensalt_blowfish_rn; + else +-- +1.7.3.4 + diff --git a/crypt_blowfish-1.2-versioning.diff b/crypt_blowfish-1.2-versioning.diff new file mode 100644 index 0000000..45fdaaa --- /dev/null +++ b/crypt_blowfish-1.2-versioning.diff @@ -0,0 +1,53 @@ +Index: crypt_blowfish-1.2/wrapper.c +=================================================================== +--- crypt_blowfish-1.2/wrapper.c ++++ crypt_blowfish-1.2/wrapper.c +@@ -38,6 +38,7 @@ + #define CRYPT_GENSALT_OUTPUT_SIZE (7 + 22 + 1) + + #if defined(__GLIBC__) && defined(_LIBC) ++#include + #define __SKIP_GNU + #endif + #include "ow-crypt.h" +@@ -291,14 +292,34 @@ char *__crypt_gensalt(const char *prefix + } + + #if defined(__GLIBC__) && defined(_LIBC) +-weak_alias(__crypt_rn, crypt_rn) +-weak_alias(__crypt_ra, crypt_ra) + weak_alias(__crypt_r, crypt_r) + weak_alias(__crypt, crypt) +-weak_alias(__crypt_gensalt_rn, crypt_gensalt_rn) +-weak_alias(__crypt_gensalt_ra, crypt_gensalt_ra) +-weak_alias(__crypt_gensalt, crypt_gensalt) +-weak_alias(crypt, fcrypt) ++weak_alias(__crypt, fcrypt) ++#if SHARED ++#if 1 // Owl has crypt_gensalt as GLIBC_2_0 so keep for compatibility ++#define ow_compat_symbol(name) \ ++ compat_symbol(libcrypt, _compat_##name, name, GLIBC_2_0); \ ++ weak_alias(__##name, _compat_##name) ++#else ++#define ow_compat_symbol(name) ++#endif ++ ++#define ow_versioned(name) \ ++ ow_compat_symbol(name) \ ++ versioned_symbol(libcrypt, _owl_##name, name, OW_CRYPT_1_0); ++#else ++#define ow_versioned(name) ++#endif // SHARED ++ ++#define ow_symbol(name) \ ++ ow_versioned(name) \ ++ weak_alias(__##name, _owl_##name) \ ++ ++ow_symbol(crypt_rn) ++ow_symbol(crypt_ra) ++ow_symbol(crypt_gensalt) ++ow_symbol(crypt_gensalt_rn) ++ow_symbol(crypt_gensalt_ra) + #endif + + #ifdef TEST diff --git a/glibc-2.14-crypt-versioning.diff b/glibc-2.14-crypt-versioning.diff new file mode 100644 index 0000000..dfbb258 --- /dev/null +++ b/glibc-2.14-crypt-versioning.diff @@ -0,0 +1,24 @@ +Index: glibc-2.14/Versions.def +=================================================================== +--- glibc-2.14.orig/Versions.def ++++ glibc-2.14/Versions.def +@@ -41,6 +41,7 @@ libc { + } + libcrypt { + GLIBC_2.0 ++ OW_CRYPT_1.0 + } + libdl { + GLIBC_2.0 +Index: glibc-2.14/crypt/Versions +=================================================================== +--- glibc-2.14.orig/crypt/Versions ++++ glibc-2.14/crypt/Versions +@@ -3,4 +3,7 @@ libcrypt { + crypt; crypt_r; encrypt; encrypt_r; fcrypt; setkey; setkey_r; + crypt_rn; crypt_ra; crypt_gensalt; crypt_gensalt_rn; crypt_gensalt_ra; + } ++ OW_CRYPT_1.0 { ++ crypt_rn; crypt_ra; crypt_gensalt; crypt_gensalt_rn; crypt_gensalt_ra; ++ } + } diff --git a/glibc.changes b/glibc.changes index 2836397..160e877 100644 --- a/glibc.changes +++ b/glibc.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Aug 25 09:44:37 UTC 2011 - lnussel@suse.de + +- use symbol version OW_CRYPT_1.0 for the Owl extensions + (crypt_r[an], crypt_gensalt.*) +- refactor sha2 gensalt patch +- document sha2 hashes in man page + ------------------------------------------------------------------- Mon Aug 22 13:12:18 UTC 2011 - aj@suse.de @@ -44,6 +52,11 @@ Fri Aug 12 14:55:12 CEST 2011 - matz@suse.de behaviour can confuse current users. [bnc #711829] (patch glibc-revert-fseek-on-fclose.diff) +------------------------------------------------------------------- +Fri Jul 22 13:47:23 UTC 2011 - lnussel@suse.de + +- fix signature of sha2 functions + ------------------------------------------------------------------- Thu Jul 21 12:37:09 UTC 2011 - rhafer@suse.de diff --git a/glibc.spec b/glibc.spec index 8ad119f..b85ef5d 100644 --- a/glibc.spec +++ b/glibc.spec @@ -120,6 +120,8 @@ Patch3: glibc-resolv-reload.diff Patch4: glibc-2.3.locales.diff.bz2 # PATCH-FEATURE-OPENSUSE -- add crypt_blowfish support - bnc#700876 Patch5: glibc-2.14-crypt.diff +# PATCH-FEATURE-OPENSUSE -- use separate symbol version for Owl extensions - lnussel@suse.de +Patch6: glibc-2.14-crypt-versioning.diff # PATCH-FIX-OPENSUSE add some extra information to version output - kukuk@suse.de Patch7: glibc-version.diff # PATCH-MISSING-TAG -- See http://en.opensuse.org/openSUSE:Packaging_Patches_guidelines @@ -199,7 +201,9 @@ Patch68: glibc-fix-lookup-crash.patch # PATCH-FIX-UPSTREAM Fix fopen("non-existing-file", "re") errno bnc#713146 aj@suse.de Patch69: fopen-close-exec.patch # PATCH-FEATURE-OPENSUSE -- add sha support to crypt_blowfish lnussel@suse.de -Patch80: crypt_blowfish-1.1-sha.diff +Patch80: crypt_blowfish-1.2-sha.diff +# PATCH-FEATURE-OPENSUSE -- use separate symbol version for Owl extensions - lnussel@suse.de +Patch81: crypt_blowfish-1.2-versioning.diff %description The GNU C Library provides the most important standard libraries used @@ -370,6 +374,7 @@ versions of your software. tar -xzf %SOURCE50 pushd crypt_blowfish-%{crypt_bf_version} %patch80 -p1 +%patch81 -p1 popd mv crypt/{crypt.h,gnu-crypt.h} mv crypt_blowfish-%crypt_bf_version/*.[chS] crypt/ @@ -380,6 +385,7 @@ mv crypt_blowfish-%crypt_bf_version/*.[chS] crypt/ %patch3 %patch4 %patch5 -p1 +%patch6 -p1 %patch7 %patch8 %patch12