void scramble(char *to, _MYSQL_DATA *_psSessionData, const char *message, const char *password) { SHA1_CONTEXT sha1_context; uint8 hash_stage1[SHA1_HASH_SIZE]; uint8 hash_stage2[SHA1_HASH_SIZE]; sha1_reset(&sha1_context); /* Stock pass-the-hash Attacks do not appear feasible. However, if another conversation is intercepted and the SHA1 hash (hash_stage2) is known, hash_stage1 could probably be derived. A new reply could then be generated based on that information. Of course, if we already have this sort of network access, what are we messing with this for? */ if (_psSessionData->hashFlag == HASH) if ( (strncmp(password, "*", 1) == 0) && (strlen(password) == 2 * SHA1_HASH_SIZE + 1) ) writeError(ERR_ERROR, "[%s] MySQL 4.1 and above use a SHA1-based authentication scheme which does not appear to be susceptible to pass-the-hash style attacks.", MODULE_NAME); /* stage 1: hash password */ sha1_input(&sha1_context, (uint8 *) password, strlen(password)); sha1_result(&sha1_context, hash_stage1); /* stage 2: hash stage 1; note that hash_stage2 is stored in the database */ sha1_reset(&sha1_context); sha1_input(&sha1_context, hash_stage1, SHA1_HASH_SIZE); sha1_result(&sha1_context, hash_stage2); /* create crypt string as sha1(message, hash_stage2) */; sha1_reset(&sha1_context); sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE); /* xor allows 'from' and 'to' overlap: lets take advantage of it */ sha1_result(&sha1_context, (uint8 *) to); my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH); }
void ma_scramble_41(const unsigned char *buffer, const char *scramble, const char *password) { _MA_SHA1_CTX context; unsigned char sha1[SHA1_MAX_LENGTH]; unsigned char sha2[SHA1_MAX_LENGTH]; /* Phase 1: hash password */ ma_SHA1Init(&context); ma_SHA1Update(&context, (unsigned char *)password, strlen((char *)password)); ma_SHA1Final(sha1, &context); /* Phase 2: hash sha1 */ ma_SHA1Init(&context); ma_SHA1Update(&context, (unsigned char*)sha1, SHA1_MAX_LENGTH); ma_SHA1Final(sha2, &context); /* Phase 3: hash scramble + sha2 */ ma_SHA1Init(&context); ma_SHA1Update(&context, (unsigned char *)scramble, SCRAMBLE_LENGTH); ma_SHA1Update(&context, (unsigned char*)sha2, SHA1_MAX_LENGTH); ma_SHA1Final((unsigned char *)buffer, &context); /* let's crypt buffer now */ my_crypt((uchar *)buffer, (const unsigned char *)buffer, (const unsigned char *)sha1, SHA1_MAX_LENGTH); }
void scramble(char *to, const char *message, const char *password) { SHA1_CONTEXT sha1_context; uint8 hash_stage1[SHA1_HASH_SIZE]; uint8 hash_stage2[SHA1_HASH_SIZE]; mysql_sha1_reset(&sha1_context); /* Stage 1: hash password */ mysql_sha1_input(&sha1_context, (uint8 *)password, (uint)strlen(password)); mysql_sha1_result(&sha1_context, hash_stage1); /* * Stage 2: * hash stage 1; * Note that hash_stage2 is stored in the database */ mysql_sha1_reset(&sha1_context); mysql_sha1_input(&sha1_context, hash_stage1, SHA1_HASH_SIZE); mysql_sha1_result(&sha1_context, hash_stage2); /* Create crypt string as sha1(message, hash_stage2) */; mysql_sha1_reset(&sha1_context); mysql_sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE); /* Xor allows 'from' and 'to' overlap: lets take advantage of it */ mysql_sha1_result(&sha1_context, (uint8 *) to); my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH); }
char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) { char *encrypted; encrypted = my_crypt(clear, salt); if (cleanup) my_crypt_cleanup(); return encrypted; }
void get_hash_stage1 (const char *scramble_arg, const char *message, const uint8 * hash_stage2, uint8 * hash_stage1) { SHA1_CONTEXT sha1_context; mysql_sha1_reset (&sha1_context); /* create key to encrypt scramble */ mysql_sha1_input (&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); mysql_sha1_input (&sha1_context, hash_stage2, SHA1_HASH_SIZE); mysql_sha1_result (&sha1_context, hash_stage1); /* encrypt scramble */ my_crypt ((char *) hash_stage1, hash_stage1, (const uchar *) scramble_arg, SCRAMBLE_LENGTH); }
void scramble(char *to, const char *message, const char *password) { uint8 hash_stage1[SHA1_HASH_SIZE]; uint8 hash_stage2[SHA1_HASH_SIZE]; /* Two stage SHA1 hash of the password. */ compute_two_stage_sha1_hash(password, strlen(password), hash_stage1, hash_stage2); /* create crypt string as sha1(message, hash_stage2) */; compute_sha1_hash_multi((uint8 *) to, message, SCRAMBLE_LENGTH, (const char *) hash_stage2, SHA1_HASH_SIZE); my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH); }
my_bool check_scramble(const uchar *scramble_arg, const char *message, const uint8 *hash_stage2) { uint8 buf[SHA1_HASH_SIZE]; uint8 hash_stage2_reassured[SHA1_HASH_SIZE]; /* create key to encrypt scramble */ compute_sha1_hash_multi(buf, message, SCRAMBLE_LENGTH, (const char *) hash_stage2, SHA1_HASH_SIZE); /* encrypt scramble */ my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH); /* now buf supposedly contains hash_stage1: so we can get hash_stage2 */ compute_sha1_hash(hash_stage2_reassured, (const char *) buf, SHA1_HASH_SIZE); return MY_TEST(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE)); }
void scramble_with_hash_stage1 (char *to, const char *message, const unsigned char *hash_stage1) { SHA1_CONTEXT sha1_context; uint8 hash_stage2[SHA1_HASH_SIZE]; /* stage 2: hash stage 1; note that hash_stage2 is stored in the database */ mysql_sha1_reset (&sha1_context); mysql_sha1_input (&sha1_context, hash_stage1, SHA1_HASH_SIZE); mysql_sha1_result (&sha1_context, hash_stage2); /* create crypt string as sha1(message, hash_stage2) */ ; mysql_sha1_reset (&sha1_context); mysql_sha1_input (&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); mysql_sha1_input (&sha1_context, hash_stage2, SHA1_HASH_SIZE); /* xor allows 'from' and 'to' overlap: lets take advantage of it */ mysql_sha1_result (&sha1_context, (uint8 *) to); my_crypt (to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH); }
my_bool check_scramble(const char *scramble_arg, const char *message, const uint8 *hash_stage2) { SHA1_CONTEXT sha1_context; uint8 buf[SHA1_HASH_SIZE]; uint8 hash_stage2_reassured[SHA1_HASH_SIZE]; mysql_sha1_reset(&sha1_context); /* create key to encrypt scramble */ mysql_sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE); mysql_sha1_result(&sha1_context, buf); /* encrypt scramble */ my_crypt((char *) buf, buf, (const uchar *) scramble_arg, SCRAMBLE_LENGTH); /* now buf supposedly contains hash_stage1: so we can get hash_stage2 */ mysql_sha1_reset(&sha1_context); mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE); mysql_sha1_result(&sha1_context, hash_stage2_reassured); return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE); }