/* The precalc and import routines here rely on the fact that we pad * the key out to 64 bytes and use that to initialize the md5 * contexts, and that updating an md5 context with 64 bytes of data * leaves nothing left over; all of the interesting state is contained * in the state field, and none of it is left over in the count and * buffer fields. So all we have to do is save the state field; we * can zero the others when we reload it. Which is why the decision * was made to pad the key out to 64 bytes in the first place. */ void pwsf_hmac_md5_precalc(HMAC_MD5_STATE *state, const unsigned char *key, size_t key_len) { HMAC_MD5_CTX hmac; //unsigned loop; hmac_md5_init(&hmac, key, key_len); /* for (loop = 0; loop < 4; loop++) { state->istate[loop] = htonl(hmac.ictx.state[loop]); state->ostate[loop] = htonl(hmac.octx.state[loop]); } */ state->istate[0] = htonl(hmac.ictx.A); state->istate[1] = htonl(hmac.ictx.B); state->istate[2] = htonl(hmac.ictx.C); state->istate[3] = htonl(hmac.ictx.D); state->ostate[0] = htonl(hmac.octx.A); state->ostate[1] = htonl(hmac.octx.B); state->ostate[2] = htonl(hmac.octx.C); state->ostate[3] = htonl(hmac.octx.D); memset(&hmac, 0, sizeof(hmac)); }
/* One step hmac computation * * digest may be same as text or key */ void hmac_md5(const unsigned char *text, int text_len, const unsigned char *key, int key_len, unsigned char digest[HMAC_MD5_SIZE]) { HMAC_MD5_CTX hmac; hmac_md5_init(&hmac, key, key_len); hmac_md5_update(&hmac, text, text_len); hmac_md5_final(digest, &hmac); }
static void ntlm_v2_hash(const char *user, const char *target, const unsigned char *hash_v1, unsigned char hash[NTLMSSP_V2_HASH_SIZE]) { struct hmac_md5_context ctx; hmac_md5_init(&ctx, hash_v1, NTLMSSP_HASH_SIZE); hmac_md5_ucs2le_string_ucase(&ctx, user); if (target) hmac_md5_ucs2le_string_ucase(&ctx, target); hmac_md5_final(&ctx, hash); }
void hmac_md5(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { hmac_md5_ctx ctx; memset(&ctx, 0, sizeof(ctx)); hmac_md5_init(&ctx, hmac_key, hmac_key_len); hmac_md5_update(&ctx, msg, msg_len); hmac_md5_final(&ctx, hmac); return; }
void hmac_md5_precalc(HMAC_MD5_STATE *ctx, const unsigned char *pass, int passlen) { HMAC_MD5_CTX hctx; if (passlen == 0) passlen = strlen((const char *) pass); hmac_md5_init(&hctx, pass, passlen); ctx->istate[0] = htonl(hctx.ictx.state[0]); ctx->istate[1] = htonl(hctx.ictx.state[1]); ctx->istate[2] = htonl(hctx.ictx.state[2]); ctx->istate[3] = htonl(hctx.ictx.state[3]); ctx->ostate[0] = htonl(hctx.octx.state[0]); ctx->ostate[1] = htonl(hctx.octx.state[1]); ctx->ostate[2] = htonl(hctx.octx.state[2]); ctx->ostate[3] = htonl(hctx.octx.state[3]); memset(&hctx, 0, sizeof (hctx)); }
void ntlmssp_v2_response(const char *user, const char *target, const unsigned char *hash_v1, const unsigned char *challenge, const unsigned char *blob, size_t blob_size, unsigned char response[NTLMSSP_V2_RESPONSE_SIZE]) { struct hmac_md5_context ctx; unsigned char hash[NTLMSSP_V2_HASH_SIZE]; ntlm_v2_hash(user, target, hash_v1, hash); hmac_md5_init(&ctx, hash, NTLMSSP_V2_HASH_SIZE); hmac_md5_update(&ctx, challenge, NTLMSSP_CHALLENGE_SIZE); hmac_md5_update(&ctx, blob, blob_size); hmac_md5_final(&ctx, response); safe_memset(hash, 0, sizeof(hash)); }