Index: crypt_blowfish-1.2/crypt_blowfish.c =================================================================== --- crypt_blowfish-1.2.orig/crypt_blowfish.c +++ crypt_blowfish-1.2/crypt_blowfish.c @@ -872,31 +872,3 @@ char *_crypt_blowfish_rn(const char *key __set_errno(EINVAL); /* pretend we don't support this hash type */ return NULL; } - -char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count, - const char *input, int size, char *output, int output_size) -{ - if (size < 16 || output_size < 7 + 22 + 1 || - (count && (count < 4 || count > 31)) || - prefix[0] != '$' || prefix[1] != '2' || - (prefix[2] != 'a' && prefix[2] != 'y')) { - if (output_size > 0) output[0] = '\0'; - __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); - return NULL; - } - - if (!count) count = 5; - - output[0] = '$'; - output[1] = '2'; - output[2] = prefix[2]; - output[3] = '$'; - output[4] = '0' + count / 10; - output[5] = '0' + count % 10; - output[6] = '$'; - - BF_encode(&output[7], (const BF_word *)input, 16); - output[7 + 22] = '\0'; - - return output; -} Index: crypt_blowfish-1.2/crypt_blowfish.h =================================================================== --- crypt_blowfish-1.2.orig/crypt_blowfish.h +++ crypt_blowfish-1.2/crypt_blowfish.h @@ -20,8 +20,5 @@ extern int _crypt_output_magic(const char *setting, char *output, int size); extern char *_crypt_blowfish_rn(const char *key, const char *setting, char *output, int size); -extern char *_crypt_gensalt_blowfish_rn(const char *prefix, - unsigned long count, - const char *input, int size, char *output, int output_size); #endif Index: crypt_blowfish-1.2/crypt_gensalt.c =================================================================== --- crypt_blowfish-1.2.orig/crypt_gensalt.c +++ crypt_blowfish-1.2/crypt_gensalt.c @@ -180,3 +180,69 @@ error: errno = ENOMEM; return NULL; } + + +typedef unsigned int BF_word; + +static const unsigned char BF_itoa64[64 + 1] = + "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + +static void BF_encode(char *dst, const BF_word *src, int size) +{ + const unsigned char *sptr = (const unsigned char *)src; + const unsigned char *end = sptr + size; + unsigned char *dptr = (unsigned char *)dst; + unsigned int c1, c2; + + do { + c1 = *sptr++; + *dptr++ = BF_itoa64[c1 >> 2]; + c1 = (c1 & 0x03) << 4; + if (sptr >= end) { + *dptr++ = BF_itoa64[c1]; + break; + } + + c2 = *sptr++; + c1 |= c2 >> 4; + *dptr++ = BF_itoa64[c1]; + c1 = (c2 & 0x0f) << 2; + if (sptr >= end) { + *dptr++ = BF_itoa64[c1]; + break; + } + + c2 = *sptr++; + c1 |= c2 >> 6; + *dptr++ = BF_itoa64[c1]; + *dptr++ = BF_itoa64[c2 & 0x3f]; + } while (sptr < end); +} + +char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count, + const char *input, int size, char *output, int output_size) +{ + if (size < 16 || output_size < 7 + 22 + 1 || + (count && (count < 4 || count > 31)) || + prefix[0] != '$' || prefix[1] != '2' || + (prefix[2] != 'a' && prefix[2] != 'y')) { + if (output_size > 0) output[0] = '\0'; + __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); + return NULL; + } + + if (!count) count = 5; + + output[0] = '$'; + output[1] = '2'; + output[2] = prefix[2]; + output[3] = '$'; + output[4] = '0' + count / 10; + output[5] = '0' + count % 10; + output[6] = '$'; + + BF_encode(&output[7], (const BF_word *)input, 16); + output[7 + 22] = '\0'; + + return output; +} Index: crypt_blowfish-1.2/crypt_gensalt.h =================================================================== --- crypt_blowfish-1.2.orig/crypt_gensalt.h +++ crypt_blowfish-1.2/crypt_gensalt.h @@ -28,5 +28,8 @@ extern char *_crypt_gensalt_md5_rn(const const char *input, int size, char *output, int output_size); extern char *_crypt_gensalt_sha2_rn(const char *prefix, unsigned long count, const char *input, int size, char *output, int output_size); +extern char *_crypt_gensalt_blowfish_rn(const char *prefix, + unsigned long count, + const char *input, int size, char *output, int output_size); #endif Index: crypt_blowfish-1.2/wrapper-gensalt.c =================================================================== --- /dev/null +++ crypt_blowfish-1.2/wrapper-gensalt.c @@ -0,0 +1,113 @@ +/* + * Written by Solar Designer in 2000-2011. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See crypt_blowfish.c for more information. + */ + +#include +#include + +#include +#ifndef __set_errno +#define __set_errno(val) errno = (val) +#endif + +#define CRYPT_GENSALT_OUTPUT_SIZE (7 + 22 + 1) + +#if defined(__GLIBC__) && defined(_LIBC) +#define __SKIP_GNU +#endif +#include "ow-crypt.h" + +#include "crypt_gensalt.h" + +#if !(defined(__GLIBC__) && defined(_LIBC)) +#define __crypt_gensalt_rn crypt_gensalt_rn +#define __crypt_gensalt_ra crypt_gensalt_ra +#define __crypt_gensalt crypt_gensalt +#endif + +char *__crypt_gensalt_rn(const char *prefix, unsigned long count, + const char *input, int size, char *output, int output_size) +{ + char *(*use)(const char *_prefix, unsigned long _count, + const char *_input, int _size, + char *_output, int _output_size); + + /* This may be supported on some platforms in the future */ + if (!input) { + __set_errno(EINVAL); + 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 + if (!strncmp(prefix, "$1$", 3)) + use = _crypt_gensalt_md5_rn; + else + if (prefix[0] == '_') + use = _crypt_gensalt_extended_rn; + else + if (!prefix[0] || + (prefix[0] && prefix[1] && + memchr(_crypt_itoa64, prefix[0], 64) && + memchr(_crypt_itoa64, prefix[1], 64))) + use = _crypt_gensalt_traditional_rn; + else { + __set_errno(EINVAL); + return NULL; + } + + return use(prefix, count, input, size, output, output_size); +} + +char *__crypt_gensalt_ra(const char *prefix, unsigned long count, + const char *input, int size) +{ + char output[CRYPT_GENSALT_OUTPUT_SIZE]; + char *retval; + + retval = __crypt_gensalt_rn(prefix, count, + input, size, output, sizeof(output)); + + if (retval) { + retval = strdup(retval); +#ifndef __GLIBC__ + /* strdup(3) on glibc sets errno, so we don't need to bother */ + if (!retval) + __set_errno(ENOMEM); +#endif + } + + return retval; +} + +char *__crypt_gensalt(const char *prefix, unsigned long count, + const char *input, int size) +{ + static char output[CRYPT_GENSALT_OUTPUT_SIZE]; + + return __crypt_gensalt_rn(prefix, count, + input, size, output, sizeof(output)); +} + +#if defined(__GLIBC__) && defined(_LIBC) +weak_alias(__crypt_gensalt_rn, crypt_gensalt_rn) +weak_alias(__crypt_gensalt_ra, crypt_gensalt_ra) +weak_alias(__crypt_gensalt, crypt_gensalt) +#endif + Index: crypt_blowfish-1.2/wrapper.c =================================================================== --- crypt_blowfish-1.2.orig/wrapper.c +++ crypt_blowfish-1.2/wrapper.c @@ -35,7 +35,6 @@ #endif #define CRYPT_OUTPUT_SIZE (7 + 22 + 31 + 1) -#define CRYPT_GENSALT_OUTPUT_SIZE (7 + 22 + 1) #if defined(__GLIBC__) && defined(_LIBC) #define __SKIP_GNU @@ -43,7 +42,6 @@ #include "ow-crypt.h" #include "crypt_blowfish.h" -#include "crypt_gensalt.h" #if defined(__GLIBC__) && defined(_LIBC) /* crypt.h from glibc-crypt-2.1 will define struct crypt_data for us */ @@ -209,88 +207,11 @@ char *crypt(const char *key, const char crypt_rn(key, setting, output, sizeof(output)), setting, output, sizeof(output)); } - -#define __crypt_gensalt_rn crypt_gensalt_rn -#define __crypt_gensalt_ra crypt_gensalt_ra -#define __crypt_gensalt crypt_gensalt -#endif - -char *__crypt_gensalt_rn(const char *prefix, unsigned long count, - const char *input, int size, char *output, int output_size) -{ - char *(*use)(const char *_prefix, unsigned long _count, - const char *_input, int _size, - char *_output, int _output_size); - - /* This may be supported on some platforms in the future */ - if (!input) { - __set_errno(EINVAL); - 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 - if (!strncmp(prefix, "$1$", 3)) - use = _crypt_gensalt_md5_rn; - else - if (prefix[0] == '_') - use = _crypt_gensalt_extended_rn; - else - if (!prefix[0] || - (prefix[0] && prefix[1] && - memchr(_crypt_itoa64, prefix[0], 64) && - memchr(_crypt_itoa64, prefix[1], 64))) - use = _crypt_gensalt_traditional_rn; - else { - __set_errno(EINVAL); - return NULL; - } - - return use(prefix, count, input, size, output, output_size); -} - -char *__crypt_gensalt_ra(const char *prefix, unsigned long count, - const char *input, int size) -{ - char output[CRYPT_GENSALT_OUTPUT_SIZE]; - char *retval; - - retval = __crypt_gensalt_rn(prefix, count, - input, size, output, sizeof(output)); - - if (retval) { - retval = strdup(retval); -#ifndef __GLIBC__ - /* strdup(3) on glibc sets errno, so we don't need to bother */ - if (!retval) - __set_errno(ENOMEM); #endif - } - - return retval; -} - -char *__crypt_gensalt(const char *prefix, unsigned long count, - const char *input, int size) -{ - static char output[CRYPT_GENSALT_OUTPUT_SIZE]; - - return __crypt_gensalt_rn(prefix, count, - input, size, output, sizeof(output)); -} #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) #endif