/* saltdecode.c -- Decode a given password salt into a readable format * * GPLv2 only - Copyright (C) 2009 - 2012 * David Sommerseth * * 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. * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ /** * @file eurephia_saltdecode.c * @author David Sommerseth * @date 2009-03-29 * * @brief Simple utility which decodes a eurephia SHA512 hash salt * */ #include #include #include #include #include #include #define ROUNDS_MIN 1000 /**< Minimum hashing rounds to acknowledge */ #define ROUNDS_MAX 999999999 /**< Maximum hashing rounds to acknowledge */ /** * 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; for( n = 0; n < strlen_nullsafe(pwd); n++ ) { t += pwd[n]; } for( n = 0; n < 4; n++ ) { saltinfo_p2 <<= 8; saltinfo_p2 += (strlen_nullsafe(pwd) ^ (t % 0xff)); } return saltinfo_p2; } /** * 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; assert(insalt != NULL && pwd != NULL); if( sscanf(insalt, "%08x", &in_salt_prefix) > -1 ) { long int regen_p2 = in_salt_prefix ^ get_salt_p2(pwd); return regen_p2 ^ 0xAAAAAAAA; } else { return -1; } } /** * saltdecode main function * * @param argc argument counter * @param argv argument table * * @return Returns 0 on success, otherwise 1. */ int main(int argc, char **argv) { char key[258]; unsigned int saltinfo = 0; size_t rounds = 0, salt_len = 0; if( argc != 2 ) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } memset(&key, 0, 258); printf("\nYou will need to give the correct password for this salt.\n"); printf("If you give the wrong password, the decoded information will be wrong.\n\n"); get_console_input(key, 256, "Password:", 1); saltinfo = unpack_saltinfo(argv[1], key); memset(&key, 0, 258); salt_len = saltinfo & 0x000000ff; rounds = MAX(ROUNDS_MIN, MIN(((saltinfo & 0xffffff00) >> 8), ROUNDS_MAX)); printf("\nSalt length: %ld\nHash rounds: %ld\n\n", (unsigned long int) salt_len, (unsigned long int) rounds); return 0; }