diff options
Diffstat (limited to 'common/passwd.c')
-rw-r--r-- | common/passwd.c | 94 |
1 files changed, 88 insertions, 6 deletions
diff --git a/common/passwd.c b/common/passwd.c index 7887efb..70fc3d3 100644 --- a/common/passwd.c +++ b/common/passwd.c @@ -26,6 +26,17 @@ * */ +/** + * @file passwd.c + * @author David Sommerseth <dazo@users.sourceforge.net> + * @author Ulrich Drepper <drepper@redhat.com> + * @date 2009-03-21 + * + * @brief Functions for generating SHA512 hashes from clear-text values. Parts of this + * code is based on Ulrich Dreppers paper for implementing SHA512 hashing in glibc. + * + */ + #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif @@ -67,6 +78,14 @@ static const char b64t[64] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +/** + * Generates a phase2 salt value from a password. + * + * @param pwd Input hash + * + * @return Returns an int value containing the phase2 salt information + */ inline unsigned int get_salt_p2(const char *pwd) { int n = 0; long int saltinfo_p2 = 0, t = 0; @@ -82,12 +101,34 @@ inline unsigned int get_salt_p2(const char *pwd) { return saltinfo_p2; } + +/** + * Packs the hashing rounds value and salt length as a 8 byte hex value, and "scrambled" with + * a phase2 salt information. + * + * @param buf Return buffer where the salt info will be returned + * @param buflen Size of the buffer + * @param rounds Number of hashing rounds + * @param saltlen Length of the SHA512 salt + * @param pwd Password of the user + * + * @return Returns the length of the salt information in bytes. + */ int pack_saltinfo(char *buf, int buflen, int rounds, int saltlen, const char *pwd) { assert((buf != NULL) && (buflen > 0)); snprintf(buf, buflen, "%08x%c", (unsigned int)(((rounds<<8)+saltlen) ^ 0xAAAAAAAA) ^ get_salt_p2(pwd), 0); return strlen_nullsafe(buf); } + +/** + * This function will unpack the salt information and "unscramble" it with a given password + * + * @param insalt Input eurephia SHA512 salt string + * @param pwd Users password + * + * @return Returns the decoded salt information, containing hashing rounds and salt length. + */ unsigned int unpack_saltinfo(const char *insalt, const char *pwd) { unsigned int in_salt_prefix = 0; @@ -101,6 +142,16 @@ unsigned int unpack_saltinfo(const char *insalt, const char *pwd) { } } + +/** + * Generates a number of random characters, used to create an even more unpredictable hashing salt + * + * @param ctx eurephiaCTX + * @param saltstr Return buffer where the salt will be placed (char *) + * @param len Size of the buffer + * + * @return Returns 1 on success, otherwise 0 + */ int gen_randsaltstr(eurephiaCTX *ctx, char *saltstr, int len) { static const char randchars[] = "7+q2wertyuiopasd5fghj1kl<zxcvbnm,3.-!#%&/()9=?ZXCVBNM;:_ASD4FGHJK6L*QWE8RTYUI0OP>@£$\0"; unsigned char *rand = NULL, *ptr2 = NULL; @@ -126,6 +177,18 @@ int gen_randsaltstr(eurephiaCTX *ctx, char *saltstr, int len) { return 1; } + +/** + * Internal SHA512 hashing function. Does the real hashing job + * + * @param key The password of the user + * @param salt Salt to be used when generating the SHA512 hash + * @param maxrounds_cfg Maximum configured hashing rounds + * @param buffer Buffer where to put the SHA512 result + * @param buflen Size of the buffer + * + * @return Returns a pointer to the buffer, or NULL on failure. + */ inline char *sha512_crypt_r(const char *key, const char *salt, size_t maxrounds_cfg, char *buffer, int buflen) { unsigned char alt_result[64] @@ -157,22 +220,19 @@ inline char *sha512_crypt_r(const char *key, const char *salt, size_t maxrounds_ // The drawback is if the maxrounds later on is changed to a value which is: // passwordsalt_rounds > maxrounds_cfg * 1.5 // these passwords will be invalidated by that change. This is considered - // to be a feature and not a bug. The reason for mulitiplying by 1.5, is to + // to be a feature and not a bug. The reason for multiplying by 1.5, is to // allow a little room for a degrading max rounds. // // Without this fix, a wrong password might take several seconds or minutes to // calculate. This behaviour is not wanted as that wastes CPU cycles on something // we know is wrong. But to avoid quiting too quickly and to slow down - // bruteforce attacks directly on eurephia, we add 1 seconds sleep. + // brute-force attacks directly on eurephia, we add 1 seconds sleep. // if( rounds > (maxrounds_cfg * 1.5) ) { sleep(1); return NULL; } - //printf("%-8.8s == (%ld, %i) [%02x, %06x]\n", - // salt, (long int)rounds, (int)salt_len, (int)rounds, (int)salt_len); - if ((key - (char *) 0) % __alignof__ (uint64_t) != 0) { char *tmp = (char *) alloca (key_len + __alignof__ (uint64_t)); key = copied_key = memcpy (tmp + __alignof__ (uint64_t) @@ -373,7 +433,18 @@ inline char *sha512_crypt_r(const char *key, const char *salt, size_t maxrounds_ } -/* The main password hashing for eurephia passwords */ +/** + * The main SHA512 password hashing for eurephia passwords. Suitable when passwords needs to be + * stored on disk. + * + * @param ctx eurephiaCTX + * @param key Users password + * @param salt Salt to be used when validating the password. To generate a new SHA512 hash, set + * this parameter to NULL + * + * @return Returns a string to a buffer containing the SHA512 hash. This buffer must be cleared and + * freed when no longer needed. + */ char *eurephia_pwd_crypt(eurephiaCTX *ctx, 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 @@ -454,6 +525,17 @@ char *eurephia_pwd_crypt(eurephiaCTX *ctx, const char *key, const char *salt) { } +/** + * Very quick SHA512 hashing algorithm, to be used only when hashing is static and not suitable for + * storing of password hashes. + * + * @param salt Salt to be used when generating the hashing + * @param pwd Value to be hashed. + * + * @return Returns a pointer to buffer containing the SHA512 hash. This buffer must be cleared and freed + * when no longer needed. + */ + char *eurephia_quick_hash(const char *salt, const char *pwd) { SHA512Context sha; uint8_t sha_res[SHA512_HASH_SIZE]; |