Ejemplo n.º 1
0
void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
		      const struct nls_table *nls_cp)
{
	int rc;
	struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf;
	struct HMACMD5Context context;

	buf->blob_signature = cpu_to_le32(0x00000101);
	buf->reserved = 0;
	buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
	get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
	buf->reserved2 = 0;
	buf->names[0].type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE);
	buf->names[0].length = 0;
	buf->names[1].type = 0;
	buf->names[1].length = 0;

	/* calculate buf->ntlmv2_hash */
	rc = calc_ntlmv2_hash(ses, nls_cp);
	if (rc)
		cERROR(1, "could not get v2 hash rc %d", rc);
	CalcNTLMv2_response(ses, resp_buf);

	/* now calculate the MAC key for NTLMv2 */
	hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context);
	hmac_md5_update(resp_buf, 16, &context);
	hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context);

	memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf,
	       sizeof(struct ntlmv2_resp));
	ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp);
}
Ejemplo n.º 2
0
/* Does the NTLMv2 owfs of a user's password */
#if 0  /* function not needed yet - but will be soon */
static void
ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
		const char *domain_n, unsigned char kr_buf[16],
		const struct nls_table *nls_codepage)
{
	wchar_t *user_u;
	wchar_t *dom_u;
	int user_l, domain_l;
	struct HMACMD5Context ctx;

	/* might as well do one alloc to hold both (user_u and dom_u) */
	user_u = kmalloc(2048 * sizeof(wchar_t), GFP_KERNEL);
	if (user_u == NULL)
		return;
	dom_u = user_u + 1024;

	/* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
	   push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */

	/* BB user and domain may need to be uppercased */
	user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
	domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);

	user_l++;		/* trailing null */
	domain_l++;

	hmac_md5_init_limK_to_64(owf, 16, &ctx);
	hmac_md5_update((const unsigned char *) user_u, user_l * 2, &ctx);
	hmac_md5_update((const unsigned char *) dom_u, domain_l * 2, &ctx);
	hmac_md5_final(kr_buf, &ctx);

	kfree(user_u);
}
Ejemplo n.º 3
0
/*
  initialise the credentials state for ADS-style 128 bit session keys

  this call is made after the netr_ServerReqChallenge call
*/
static void creds_init_128bit(struct creds_CredentialState *creds,
			      const struct netr_Credential *client_challenge,
			      const struct netr_Credential *server_challenge,
			      const struct samr_Password *machine_password)
{
	unsigned char zero[4], tmp[16];
	HMACMD5Context ctx;
	struct MD5Context md5;

	ZERO_STRUCT(creds->session_key);

	memset(zero, 0, sizeof(zero));

	hmac_md5_init_rfc2104(machine_password->hash, sizeof(machine_password->hash), &ctx);	
	MD5Init(&md5);
	MD5Update(&md5, zero, sizeof(zero));
	MD5Update(&md5, client_challenge->data, 8);
	MD5Update(&md5, server_challenge->data, 8);
	MD5Final(tmp, &md5);
	hmac_md5_update(tmp, sizeof(tmp), &ctx);
	hmac_md5_final(creds->session_key, &ctx);

	creds->client = *client_challenge;
	creds->server = *server_challenge;

	des_crypt112(creds->client.data, client_challenge->data, creds->session_key, 1);
	des_crypt112(creds->server.data, server_challenge->data, creds->session_key, 1);

	creds->seed = creds->client;
}
Ejemplo n.º 4
0
static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
			    const struct nls_table *nls_cp)
{
	int rc = 0;
	int len;
	char nt_hash[16];
	struct HMACMD5Context *pctxt;
	wchar_t *user;
	wchar_t *domain;

	pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL);

	if (pctxt == NULL)
		return -ENOMEM;

	/* calculate md4 hash of password */
	E_md4hash(ses->password, nt_hash);

	/* convert Domainname to unicode and uppercase */
	hmac_md5_init_limK_to_64(nt_hash, 16, pctxt);

	/* convert ses->userName to unicode and uppercase */
	len = strlen(ses->userName);
	user = kmalloc(2 + (len * 2), GFP_KERNEL);
	if (user == NULL)
		goto calc_exit_2;
	len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
	UniStrupr(user);
	hmac_md5_update((char *)user, 2*len, pctxt);

	/* convert ses->domainName to unicode and uppercase */
	if (ses->domainName) {
		len = strlen(ses->domainName);

		domain = kmalloc(2 + (len * 2), GFP_KERNEL);
		if (domain == NULL)
			goto calc_exit_1;
		len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
					nls_cp);
		/* the following line was removed since it didn't work well
		   with lower cased domain name that passed as an option.
		   Maybe converting the domain name earlier makes sense */
		/* UniStrupr(domain); */

		hmac_md5_update((char *)domain, 2*len, pctxt);

		kfree(domain);
	}
calc_exit_1:
	kfree(user);
calc_exit_2:
	/* BB FIXME what about bytes 24 through 40 of the signing key?
	   compare with the NTLM example */
	hmac_md5_final(ses->server->ntlmv2_hash, pctxt);

	kfree(pctxt);
	return rc;
}
Ejemplo n.º 5
0
void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, unsigned char *digest) {
    HMACMD5Context ctx;

    hmac_md5_init_limK_to_64(key, 16, &ctx);
    if (data_len != 0) {
        hmac_md5_update(data, data_len, &ctx);
    }
    hmac_md5_final(digest, &ctx);
}
Ejemplo n.º 6
0
int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *ses,
			       const struct nls_table *nls_info)
{
	char temp_hash[16];
	struct HMACMD5Context ctx;
	char *ucase_buf;
	__le16 *unicode_buf;
	unsigned int i, user_name_len, dom_name_len;

	if (ses == NULL)
		return -EINVAL;

	E_md4hash(ses->password, temp_hash);

	hmac_md5_init_limK_to_64(temp_hash, 16, &ctx);
	user_name_len = strlen(ses->userName);
	if (user_name_len > MAX_USERNAME_SIZE)
		return -EINVAL;
	if (ses->domainName == NULL)
		return -EINVAL; /* BB should we use CIFS_LINUX_DOM */
	dom_name_len = strlen(ses->domainName);
	if (dom_name_len > MAX_USERNAME_SIZE)
		return -EINVAL;

	ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL);
	if (ucase_buf == NULL)
		return -ENOMEM;
	unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL);
	if (unicode_buf == NULL) {
		kfree(ucase_buf);
		return -ENOMEM;
	}

	for (i = 0; i < user_name_len; i++)
		ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]];
	ucase_buf[i] = 0;
	user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf,
				      MAX_USERNAME_SIZE*2, nls_info);
	unicode_buf[user_name_len] = 0;
	user_name_len++;

	for (i = 0; i < dom_name_len; i++)
		ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]];
	ucase_buf[i] = 0;
	dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf,
				     MAX_USERNAME_SIZE*2, nls_info);

	unicode_buf[user_name_len + dom_name_len] = 0;
	hmac_md5_update((const unsigned char *) unicode_buf,
		(user_name_len+dom_name_len)*2, &ctx);

	hmac_md5_final(ses->server->ntlmv2_hash, &ctx);
	kfree(ucase_buf);
	kfree(unicode_buf);
	return 0;
}
Ejemplo n.º 7
0
static void
SMBsesskeygen_ntv2(const unsigned char kr[16],
		   const unsigned char *nt_resp, __u8 sess_key[16])
{
	struct HMACMD5Context ctx;

	hmac_md5_init_limK_to_64(kr, 16, &ctx);
	hmac_md5_update(nt_resp, 16, &ctx);
	hmac_md5_final((unsigned char *) sess_key, &ctx);
}
Ejemplo n.º 8
0
/* 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);
}
Ejemplo n.º 9
0
/***********************************************************
 single function to calculate an HMAC MD5 digest from data
 using optimised hmacmd5 init method because the key is 16 bytes.
************************************************************/
void hmac_md5(const unsigned char *key, const unsigned char *data,
              int data_len, unsigned char *digest)
{
	HMACMD5Context ctx;

	hmac_md5_init_K16(key, &ctx);
	if (data_len != 0)
		hmac_md5_update(data, data_len, &ctx);
	hmac_md5_final(digest, &ctx);
}
Ejemplo n.º 10
0
/***********************************************************
 single function to calculate an HMAC MD5 digest from data.
 use the microsoft hmacmd5 init method because the key is 16 bytes.
************************************************************/
_PUBLIC_ void hmac_md5(const uint8_t key[16], const uint8_t *data, int data_len, uint8_t *digest)
{
	HMACMD5Context ctx;
	hmac_md5_init_limK_to_64(key, 16, &ctx);
	if (data_len != 0)
	{
		hmac_md5_update(data, data_len, &ctx);
	}
	hmac_md5_final(digest, &ctx);
}
Ejemplo n.º 11
0
/* Does both the NTLMv2 owfs of a user's password */
bool ntv2_owf_gen(const uchar owf[16],
		  const char *user_in, const char *domain_in,
		  bool upper_case_domain, /* Transform the domain into UPPER case */
		  uchar kr_buf[16])
{
	smb_ucs2_t *user;
	smb_ucs2_t *domain;
	
	size_t user_byte_len;
	size_t domain_byte_len;

	HMACMD5Context ctx;

	if (!push_ucs2_allocate(&user, user_in, &user_byte_len)) {
		DEBUG(0, ("push_uss2_allocate() for user failed: %s\n",
			  strerror(errno)));
		return False;
	}

	if (!push_ucs2_allocate(&domain, domain_in, &domain_byte_len)) {
		DEBUG(0, ("push_uss2_allocate() for domain failed: %s\n",
			  strerror(errno)));
		SAFE_FREE(user);
		return False;
	}

	strupper_w(user);

	if (upper_case_domain)
		strupper_w(domain);

	SMB_ASSERT(user_byte_len >= 2);
	SMB_ASSERT(domain_byte_len >= 2);

	/* We don't want null termination */
	user_byte_len = user_byte_len - 2;
	domain_byte_len = domain_byte_len - 2;
	
	hmac_md5_init_limK_to_64(owf, 16, &ctx);
	hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx);
	hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx);
	hmac_md5_final(kr_buf, &ctx);

#ifdef DEBUG_PASSWORD
	DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n"));
	dump_data(100, (uint8 *)user, user_byte_len);
	dump_data(100, (uint8 *)domain, domain_byte_len);
	dump_data(100, (uint8 *)owf, 16);
	dump_data(100, (uint8 *)kr_buf, 16);
#endif

	SAFE_FREE(user);
	SAFE_FREE(domain);
	return True;
}
Ejemplo n.º 12
0
void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_response)
{
	struct HMACMD5Context context;
	memcpy(v2_session_response + 8, ses->server->cryptKey,8);
	/* gen_blob(v2_session_response + 16); */
	hmac_md5_init_limK_to_64(ses->server->mac_signing_key, 16, &context);

	hmac_md5_update(ses->server->cryptKey,8,&context);
/*	hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */

	hmac_md5_final(v2_session_response,&context);
}
Ejemplo n.º 13
0
static void
SMBOWFencrypt_ntv2(const unsigned char kr[16],
		   const struct data_blob *srv_chal,
		   const struct data_blob *cli_chal, unsigned char resp_buf[16])
{
	struct HMACMD5Context ctx;

	hmac_md5_init_limK_to_64(kr, 16, &ctx);
	hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
	hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
	hmac_md5_final(resp_buf, &ctx);
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
void CalcNTLMv2_response(const struct cifsSesInfo * ses, char * v2_session_response)
{
	struct HMACMD5Context context;
	/* rest of v2 struct already generated */
	memcpy(v2_session_response + 8, ses->server->cryptKey,8);
	hmac_md5_init_limK_to_64(ses->server->mac_signing_key, 16, &context);

	hmac_md5_update(v2_session_response+8, 
			sizeof(struct ntlmv2_resp) - 8, &context);

	hmac_md5_final(v2_session_response,&context);
/*	cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
void SMBsesskeygen_ntv2(const uint8_t kr[16],
			const uint8_t * nt_resp, uint8_t sess_key[16])
{
	/* a very nice, 128 bit, variable session key */

	HMACMD5Context ctx;

	hmac_md5_init_limK_to_64(kr, 16, &ctx);
	hmac_md5_update(nt_resp, 16, &ctx);
	hmac_md5_final((uint8_t *)sess_key, &ctx);

#ifdef DEBUG_PASSWORD
	DEBUG(100, ("SMBsesskeygen_ntv2:\n"));
	dump_data(100, sess_key, 16);
#endif
}
Ejemplo n.º 18
0
static void creds_init_128(struct dcinfo *dc,
				const DOM_CHAL *clnt_chal_in,
				const DOM_CHAL *srv_chal_in,
				const unsigned char mach_pw[16])
{
	unsigned char zero[4], tmp[16];
	HMACMD5Context ctx;
	struct MD5Context md5;

	/* Just in case this isn't already there */
	memcpy(dc->mach_pw, mach_pw, 16);

	ZERO_STRUCT(dc->sess_key);

	memset(zero, 0, sizeof(zero));

	hmac_md5_init_rfc2104(mach_pw, 16, &ctx);
	MD5Init(&md5);
	MD5Update(&md5, zero, sizeof(zero));
	MD5Update(&md5, clnt_chal_in->data, 8);
	MD5Update(&md5, srv_chal_in->data, 8);
	MD5Final(tmp, &md5);
	hmac_md5_update(tmp, sizeof(tmp), &ctx);
	hmac_md5_final(dc->sess_key, &ctx);

	/* debug output */
	DEBUG(5,("creds_init_128\n"));
	DEBUG(5,("\tclnt_chal_in: %s\n", credstr(clnt_chal_in->data)));
	DEBUG(5,("\tsrv_chal_in : %s\n", credstr(srv_chal_in->data)));
	dump_data_pw("\tsession_key ", (const unsigned char *)dc->sess_key, 16);

	/* Generate the next client and server creds. */
	
	des_crypt112(dc->clnt_chal.data,		/* output */
			clnt_chal_in->data,		/* input */
			dc->sess_key,			/* input */
			1);

	des_crypt112(dc->srv_chal.data,			/* output */
			srv_chal_in->data,		/* input */
			dc->sess_key,			/* input */
			1);

	/* Seed is the client chal. */
	memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
}
Ejemplo n.º 19
0
void smb_key_derivation(const uint8_t *KI, size_t KI_len,
			uint8_t KO[16])
{
	static const uint8_t SSKeyHash[256] = {
		0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
		0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
		0x72, 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x55,
		0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x07,
		0x6e, 0x28, 0x2e, 0x69, 0x88, 0x10, 0xb3, 0xdb,
		0x01, 0x55, 0x72, 0xfb, 0x74, 0x14, 0xfb, 0xc4,
		0xc5, 0xaf, 0x3b, 0x41, 0x65, 0x32, 0x17, 0xba,
		0xa3, 0x29, 0x08, 0xc1, 0xde, 0x16, 0x61, 0x7e,
		0x66, 0x98, 0xa4, 0x0b, 0xfe, 0x06, 0x83, 0x53,
		0x4d, 0x05, 0xdf, 0x6d, 0xa7, 0x51, 0x10, 0x73,
		0xc5, 0x50, 0xdc, 0x5e, 0xf8, 0x21, 0x46, 0xaa,
		0x96, 0x14, 0x33, 0xd7, 0x52, 0xeb, 0xaf, 0x1f,
		0xbf, 0x36, 0x6c, 0xfc, 0xb7, 0x1d, 0x21, 0x19,
		0x81, 0xd0, 0x6b, 0xfa, 0x77, 0xad, 0xbe, 0x18,
		0x78, 0xcf, 0x10, 0xbd, 0xd8, 0x78, 0xf7, 0xd3,
		0xc6, 0xdf, 0x43, 0x32, 0x19, 0xd3, 0x9b, 0xa8,
		0x4d, 0x9e, 0xaa, 0x41, 0xaf, 0xcb, 0xc6, 0xb9,
		0x34, 0xe7, 0x48, 0x25, 0xd4, 0x88, 0xc4, 0x51,
		0x60, 0x38, 0xd9, 0x62, 0xe8, 0x8d, 0x5b, 0x83,
		0x92, 0x7f, 0xb5, 0x0e, 0x1c, 0x2d, 0x06, 0x91,
		0xc3, 0x75, 0xb3, 0xcc, 0xf8, 0xf7, 0x92, 0x91,
		0x0b, 0x3d, 0xa1, 0x10, 0x5b, 0xd5, 0x0f, 0xa8,
		0x3f, 0x5d, 0x13, 0x83, 0x0a, 0x6b, 0x72, 0x93,
		0x14, 0x59, 0xd5, 0xab, 0xde, 0x26, 0x15, 0x6d,
		0x60, 0x67, 0x71, 0x06, 0x6e, 0x3d, 0x0d, 0xa7,
		0xcb, 0x70, 0xe9, 0x08, 0x5c, 0x99, 0xfa, 0x0a,
		0x5f, 0x3d, 0x44, 0xa3, 0x8b, 0xc0, 0x8d, 0xda,
		0xe2, 0x68, 0xd0, 0x0d, 0xcd, 0x7f, 0x3d, 0xf8,
		0x73, 0x7e, 0x35, 0x7f, 0x07, 0x02, 0x0a, 0xb5,
		0xe9, 0xb7, 0x87, 0xfb, 0xa1, 0xbf, 0xcb, 0x32,
		0x31, 0x66, 0x09, 0x48, 0x88, 0xcc, 0x18, 0xa3,
		0xb2, 0x1f, 0x1f, 0x1b, 0x90, 0x4e, 0xd7, 0xe1
	};
	HMACMD5Context ctx;

	hmac_md5_init_limK_to_64(KI, KI_len, &ctx);
	hmac_md5_update(SSKeyHash, sizeof(SSKeyHash), &ctx);
	hmac_md5_final(KO, &ctx);

	ZERO_STRUCT(ctx);
}
Ejemplo n.º 20
0
static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state,
        const uchar *data, size_t length,
        enum ntlmssp_direction direction,
        DATA_BLOB *sig)
{
    if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
        HMACMD5Context ctx;
        uchar seq_num[4];
        uchar digest[16];
        SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);

        hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx);
        hmac_md5_update(seq_num, 4, &ctx);
        hmac_md5_update(data, length, &ctx);
        hmac_md5_final(digest, &ctx);

        if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */
                       , ntlmssp_state->ntlmssp_seq_num)) {
            return NT_STATUS_NO_MEMORY;
        }

        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
            switch (direction) {
            case NTLMSSP_SEND:
                NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash,  sig->data+4, sig->length-4);
                break;
            case NTLMSSP_RECEIVE:
                NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash,  sig->data+4, sig->length-4);
                break;
            }
        }
    } else {
        uint32 crc;
        crc = crc32_calc_buffer((const char *)data, length);
        if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
            return NT_STATUS_NO_MEMORY;
        }

        dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
                     sizeof(ntlmssp_state->ntlmssp_hash));
        NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4);
    }
    return NT_STATUS_OK;
}
Ejemplo n.º 21
0
/* Does the md5 encryption from the Key Response for NTLMv2. */
void SMBOWFencrypt_ntv2(const uint8_t kr[16],
			const DATA_BLOB *srv_chal,
			const DATA_BLOB *smbcli_chal,
			uint8_t resp_buf[16])
{
	HMACMD5Context ctx;

	hmac_md5_init_limK_to_64(kr, 16, &ctx);
	hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
	hmac_md5_update(smbcli_chal->data, smbcli_chal->length, &ctx);
	hmac_md5_final(resp_buf, &ctx);

#ifdef DEBUG_PASSWORD
	DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, smbcli_chal, resp_buf\n"));
	dump_data(100, srv_chal->data, srv_chal->length);
	dump_data(100, smbcli_chal->data, smbcli_chal->length);
	dump_data(100, resp_buf, 16);
#endif
}
Ejemplo n.º 22
0
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));
}
Ejemplo n.º 23
0
/* Calculate the LMv2 response for the given challenge, using the
   specified authentication identity (username and domain), password
   and client nonce.
*/
static int crypt_all(int *pcount, struct db_salt *salt)
{
	int count = *pcount;
	int i = 0;

#ifdef _OPENMP
#pragma omp parallel for
	for(i = 0; i < count; i++)
#endif
	{
		unsigned char ntlm_v2_hash[16];
		HMACMD5Context ctx; // can't be moved above the OMP pragma

		if (!keys_prepared) {
			int len;
			unsigned char ntlm[16];
			/* Generate 16-byte NTLM hash */
			len = E_md4hash(saved_plain[i], saved_len[i], ntlm);

			// We do key setup of the next HMAC_MD5 here (once per salt)
			hmac_md5_init_K16(ntlm, &saved_ctx[i]);

			if (len <= 0)
				saved_plain[i][-len] = 0; // match truncation
		}

		/* HMAC-MD5(Username + Domain, NTLM Hash) */
		memcpy(&ctx, &saved_ctx[i], sizeof(ctx));
		hmac_md5_update(&challenge[17], (int)challenge[16], &ctx);
		hmac_md5_final(ntlm_v2_hash, &ctx);

		/* Generate 16-byte non-client nonce portion of LMv2 Response */
		/* HMAC-MD5(Challenge + Nonce, NTLMv2 Hash) + Nonce */
		hmac_md5(ntlm_v2_hash, challenge, 16, (unsigned char*)output[i]);
	}
	keys_prepared = 1;

	return count;
}
Ejemplo n.º 24
0
/* Calculate the NTLMv2 response for the given challenge, using the
   specified authentication identity (username and domain), password
   and client nonce.

   challenge: Identity length, Identity\0, Challenge Size, Server Challenge + Client Challenge
*/
static int crypt_all(int *pcount, struct db_salt *salt)
{
	int count = *pcount;
	int identity_length, challenge_size;
	int i = 0;

	/* --- HMAC #1 Calculations --- */
	identity_length = challenge[0];
	challenge_size = (*(challenge + 1 + identity_length + 1) << 8) | *(challenge + 1 + identity_length + 2);

#ifdef _OPENMP
#pragma omp parallel for
	for(i=0; i<count; i++)
#endif
	{
		unsigned char ntlm_v2_hash[16];
		HMACMD5Context ctx;

		if (!keys_prepared) {
			unsigned char ntlm[16];
			int len;

			/* Generate 16-byte NTLM hash */
			len = E_md4hash(saved_plain[i], saved_len[i], ntlm);

			// We do key setup of the next HMAC_MD5 here (once per salt)
			hmac_md5_init_K16(ntlm, &saved_ctx[i]);

			if (len <= 0)
				saved_plain[i][-len] = 0; // match truncation
		}

		/* HMAC-MD5(Username + Domain, NTLM Hash) */
		memcpy(&ctx, &saved_ctx[i], sizeof(ctx));
		hmac_md5_update((unsigned char *)&challenge[1], identity_length, &ctx);
		hmac_md5_final(ntlm_v2_hash, &ctx);

		/* --- Blob Construction --- */

		/*
		    The blob consists of the target (from Type 2 message), client nonce and timestamp.
		    This data was provided by the client during authentication and we can use it as is.
		*/

		/* --- HMAC #2 Caculations --- */

		/*
		  The (server) challenge from the Type 2 message is concatenated with the blob. The
		  HMAC-MD5 message authentication code algorithm is applied to this value using the
		  16-byte NTLMv2 hash (calculated above) as the key. This results in a 16-byte output
		  value.
		*/

		/*
		   Generate 16-byte non-client nonce portion of NTLMv2 Response
		   HMAC-MD5(Challenge + Nonce, NTLMv2 Hash)

		   The length of the challenge was set in get_salt(). We find the server
		   challenge and blob following the identity and challenge size value.
		   challenge -> Identity length, Identity\0, Size (2 bytes), Server Challenge + Client Challenge (Blob)
		*/
		hmac_md5(ntlm_v2_hash, challenge + 1 + identity_length + 1 + 2, challenge_size, (unsigned char*)output[i]);
	}
	keys_prepared = 1;

	return count;
}
Ejemplo n.º 25
0
/* Calculate the NTLMv2 response for the given challenge, using the
   specified authentication identity (username and domain), password 
   and client nonce.
  
   challenge: Identity \0 Challenge Size \0 Server Challenge + Client Challenge
*/
static void netntlmv2_crypt_all(int count)
{
  HMACMD5Context ctx;
  unsigned char ntlm[16];
  unsigned char ntlm_v2_hash[16];
  uchar *identity = NULL;
  int identity_length = 0;
  int16 identity_usc[129];
  int identity_usc_length = 0;
  int challenge_size = 0; 

  memset(ntlm, 0, 16);
  memset(ntlm_v2_hash, 0, 16);
  memset(output, 0, 16);
  memset(identity_usc, 0, 129);
  identity_usc_length = 0;

  /* --- HMAC #1 Caculations --- */

  /* Convert identity (username + domain) string to NT unicode */
  identity_length = strlen((char *)challenge);
  identity = challenge;

  ntlmv2_mbstowcs(identity_usc, identity, identity_length);
  identity_usc_length = ntlmv2_wcslen(identity_usc) * sizeof(int16);

  /* Generate 16-byte NTLM hash */
  E_md4hash(saved_plain, ntlm);

  /* Generate 16-byte NTLMv2 Hash */
  /* HMAC-MD5(Username + Domain, NTLM Hash) */
  hmac_md5_init_limK_to_64(ntlm, 16, &ctx);
  hmac_md5_update((const unsigned char *)identity_usc, identity_usc_length, &ctx);
  hmac_md5_final(ntlm_v2_hash, &ctx);

  /* --- Blob Construction --- */

  /*  
    The blob consists of the target (from Type 2 message), client nonce and timestamp. 
    This data was provided by the client during authentication and we can use it as is. 
  */

  /* --- HMAC #2 Caculations --- */

  /*
    The (server) challenge from the Type 2 message is concatenated with the blob. The 
    HMAC-MD5 message authentication code algorithm is applied to this value using the 
    16-byte NTLMv2 hash (calculated above) as the key. This results in a 16-byte output 
    value.
  */

  /* 
    Generate 16-byte non-client nonce portion of NTLMv2 Response 
    HMAC-MD5(Challenge + Nonce, NTLMv2 Hash)
  
    The length of the challenge was set in netntlmv2_get_salt(). We find the server
    challenge and blob following the identity and challenge size value.
    challenge -> Identity \0 Size (2 bytes) \0 Server Challenge + Client Challenge (Blob)
  */
  challenge_size = (*(challenge + identity_length + 1) << 8) | *(challenge + identity_length + 2);

  hmac_md5_init_limK_to_64(ntlm_v2_hash, 16, &ctx);
  hmac_md5_update(challenge + identity_length + 1 + 2 + 1, challenge_size, &ctx); 
  hmac_md5_final(output, &ctx);
}
Ejemplo n.º 26
0
/* Does both the NTLMv2 owfs of a user's password */
tree_cell *
nasl_ntv2_owf_gen (lex_ctxt * lexic)
{
  const uchar *owf_in = (uchar *) get_str_var_by_name (lexic, "owf");
  int owf_in_len = get_var_size_by_name (lexic, "owf");
  char *user_in = get_str_var_by_name (lexic, "login");
  int user_in_len = get_var_size_by_name (lexic, "login");
  char *domain_in = get_str_var_by_name (lexic, "domain");
  int domain_len = get_var_size_by_name (lexic, "domain");
  char *src_user, *src_domain;
  smb_ucs2_t *user, *dst_user, val_user;
  smb_ucs2_t *domain, *dst_domain, val_domain;
  int i;
  size_t user_byte_len;
  size_t domain_byte_len;
  tree_cell *retc;
  uchar *kr_buf;
  HMACMD5Context ctx;

  if (owf_in_len < 0 || owf_in == NULL || user_in_len < 0 || user_in == NULL
      || domain_len < 0 || domain_in == NULL)
    {
      nasl_perror (lexic,
                   "Syntax : ntv2_owf_gen(owf:<o>, login:<l>, domain:<d>)\n");
      return NULL;
    }

  assert (owf_in_len == 16);

  user_byte_len = sizeof (smb_ucs2_t) * (strlen (user_in) + 1);
  user = emalloc (user_byte_len);
  dst_user = user;
  src_user = user_in;

  for (i = 0; i < user_in_len; i++)
    {
      val_user = *src_user;
      *dst_user = val_user;
      dst_user++;
      src_user++;
      if (val_user == 0)
        break;
    }

  domain_byte_len = sizeof (smb_ucs2_t) * (strlen (domain_in) + 1);
  domain = emalloc (domain_byte_len);
  dst_domain = domain;
  src_domain = domain_in;

  for (i = 0; i < domain_len; i++)
    {
      val_domain = *src_domain;
      *dst_domain = val_domain;

      dst_domain++;
      src_domain++;
      if (val_domain == 0)
        break;
    }

  strupper_w (user);
  strupper_w (domain);

  assert (user_byte_len >= 2);
  assert (domain_byte_len >= 2);

  /* We don't want null termination */
  user_byte_len = user_byte_len - 2;
  domain_byte_len = domain_byte_len - 2;

  kr_buf = emalloc (16);

  hmac_md5_init_limK_to_64 (owf_in, 16, &ctx);
  hmac_md5_update ((const unsigned char *) user, user_byte_len, &ctx);
  hmac_md5_update ((const unsigned char *) domain, domain_byte_len, &ctx);
  hmac_md5_final (kr_buf, &ctx);

  efree (&user);
  efree (&domain);

  retc = alloc_tree_cell (0, NULL);
  retc->type = CONST_DATA;
  retc->size = 16;
  retc->x.str_val = (char *) kr_buf;

  return retc;
}
Ejemplo n.º 27
0
/* Does both the NTLMv2 owfs of a user's password */
bool ntv2_owf_gen(const uint8_t owf[16],
		  const char *user_in, const char *domain_in,
		  uint8_t kr_buf[16])
{
	smb_ucs2_t *user;
	smb_ucs2_t *domain;
	size_t user_byte_len;
	size_t domain_byte_len;
	bool ret;

	HMACMD5Context ctx;
	TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in);

	if (!mem_ctx) {
		return false;
	}

	if (!user_in) {
		user_in = "";
	}

	if (!domain_in) {
		domain_in = "";
	}

	user_in = strupper_talloc(mem_ctx, user_in);
	if (user_in == NULL) {
		talloc_free(mem_ctx);
		return false;
	}

	ret = push_ucs2_talloc(mem_ctx, &user, user_in, &user_byte_len );
	if (!ret) {
		DEBUG(0, ("push_uss2_talloc() for user failed)\n"));
		talloc_free(mem_ctx);
		return false;
	}

	ret = push_ucs2_talloc(mem_ctx, &domain, domain_in, &domain_byte_len);
	if (!ret) {
		DEBUG(0, ("push_ucs2_talloc() for domain failed\n"));
		talloc_free(mem_ctx);
		return false;
	}

	SMB_ASSERT(user_byte_len >= 2);
	SMB_ASSERT(domain_byte_len >= 2);

	/* We don't want null termination */
	user_byte_len = user_byte_len - 2;
	domain_byte_len = domain_byte_len - 2;

	hmac_md5_init_limK_to_64(owf, 16, &ctx);
	hmac_md5_update((uint8_t *)user, user_byte_len, &ctx);
	hmac_md5_update((uint8_t *)domain, domain_byte_len, &ctx);
	hmac_md5_final(kr_buf, &ctx);

#ifdef DEBUG_PASSWORD
	DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n"));
	dump_data(100, (uint8_t *)user, user_byte_len);
	dump_data(100, (uint8_t *)domain, domain_byte_len);
	dump_data(100, owf, 16);
	dump_data(100, kr_buf, 16);
#endif

	talloc_free(mem_ctx);
	return true;
}
Ejemplo n.º 28
0
/*
 This uses the test values from rfc 2104, 2202
*/
bool torture_local_crypto_hmacmd5(struct torture_context *torture) 
{
	bool ret = true;
	uint32_t i;
	struct {
		DATA_BLOB key;
		DATA_BLOB data;
		DATA_BLOB md5;
	} testarray[8];

	TALLOC_CTX *tctx = talloc_new(torture);
	if (!tctx) { return false; };

	testarray[0].key	= data_blob_repeat_byte(0x0b, 16);
	testarray[0].data	= data_blob_string_const("Hi There");
	testarray[0].md5	= strhex_to_data_blob(tctx, "9294727a3638bb1c13f48ef8158bfc9d");

	testarray[1].key	= data_blob_string_const("Jefe");
	testarray[1].data	= data_blob_string_const("what do ya want for nothing?");
	testarray[1].md5	= strhex_to_data_blob(tctx, "750c783e6ab0b503eaa86e310a5db738");

	testarray[2].key	= data_blob_repeat_byte(0xaa, 16);
	testarray[2].data	= data_blob_repeat_byte(0xdd, 50);
	testarray[2].md5	= strhex_to_data_blob(tctx, "56be34521d144c88dbb8c733f0e8b3f6");

	testarray[3].key	= strhex_to_data_blob(tctx, "0102030405060708090a0b0c0d0e0f10111213141516171819");
	testarray[3].data	= data_blob_repeat_byte(0xcd, 50);
	testarray[3].md5	= strhex_to_data_blob(tctx, "697eaf0aca3a3aea3a75164746ffaa79");

	testarray[4].key	= data_blob_repeat_byte(0x0c, 16);
	testarray[4].data	= data_blob_string_const("Test With Truncation");
	testarray[4].md5	= strhex_to_data_blob(tctx, "56461ef2342edc00f9bab995690efd4c");

	testarray[5].key	= data_blob_repeat_byte(0xaa, 80);
	testarray[5].data	= data_blob_string_const("Test Using Larger Than Block-Size Key - Hash Key First");
	testarray[5].md5	= strhex_to_data_blob(tctx, "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd");

	testarray[6].key	= data_blob_repeat_byte(0xaa, 80);
	testarray[6].data	= data_blob_string_const("Test Using Larger Than Block-Size Key "
							 "and Larger Than One Block-Size Data");
	testarray[6].md5	= strhex_to_data_blob(tctx, "6f630fad67cda0ee1fb1f562db3aa53e");

	testarray[7].key        = data_blob(NULL, 0);

	for (i=0; testarray[i].key.data; i++) {
		HMACMD5Context ctx;
		uint8_t md5[16];
		int e;

		hmac_md5_init_rfc2104(testarray[i].key.data, testarray[i].key.length, &ctx);
		hmac_md5_update(testarray[i].data.data, testarray[i].data.length, &ctx);
		hmac_md5_final(md5, &ctx);

		e = memcmp(testarray[i].md5.data,
			   md5,
			   MIN(testarray[i].md5.length, sizeof(md5)));
		if (e != 0) {
			printf("hmacmd5 test[%u]: failed\n", i);
			dump_data(0, testarray[i].key.data, testarray[i].key.length);
			dump_data(0, testarray[i].data.data, testarray[i].data.length);
			dump_data(0, testarray[i].md5.data, testarray[i].md5.length);
			dump_data(0, md5, sizeof(md5));
			ret = false;
		}
	}
	talloc_free(tctx);
	return ret;
}
Ejemplo n.º 29
0
static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state,
						const uchar *data, size_t length, 
						const uchar *whole_pdu, size_t pdu_length,
						enum ntlmssp_direction direction,
						DATA_BLOB *sig,
						bool encrypt_sig)
{
	if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
		HMACMD5Context ctx;
		uchar seq_num[4];
		uchar digest[16];

		*sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
		if (!sig->data) {
			return NT_STATUS_NO_MEMORY;
		}

		switch (direction) {
			case NTLMSSP_SEND:
	                        DEBUG(100,("ntlmssp_make_packet_signature: SEND seq = %u, len = %u, pdu_len = %u\n",
					ntlmssp_state->ntlm2_send_seq_num,
					(unsigned int)length,
					(unsigned int)pdu_length));

				SIVAL(seq_num, 0, ntlmssp_state->ntlm2_send_seq_num);
				ntlmssp_state->ntlm2_send_seq_num++;
				hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, 16, &ctx);
				break;
			case NTLMSSP_RECEIVE:

				DEBUG(100,("ntlmssp_make_packet_signature: RECV seq = %u, len = %u, pdu_len = %u\n",
					ntlmssp_state->ntlm2_recv_seq_num,
					(unsigned int)length,
					(unsigned int)pdu_length));

				SIVAL(seq_num, 0, ntlmssp_state->ntlm2_recv_seq_num);
				ntlmssp_state->ntlm2_recv_seq_num++;
				hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key, 16, &ctx);
				break;
                }

		dump_data_pw("pdu data ", whole_pdu, pdu_length);

		hmac_md5_update(seq_num, 4, &ctx);
		hmac_md5_update(whole_pdu, pdu_length, &ctx);
		hmac_md5_final(digest, &ctx);

		if (encrypt_sig && (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
			switch (direction) {
			case NTLMSSP_SEND:
				arcfour_crypt_sbox(&ntlmssp_state->send_seal_arc4_state, digest, 8);
				break;
			case NTLMSSP_RECEIVE:
				arcfour_crypt_sbox(&ntlmssp_state->recv_seal_arc4_state, digest, 8);
				break;
			}
		}

		SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION);
		memcpy(sig->data + 4, digest, 8);
		memcpy(sig->data + 12, seq_num, 4);

		dump_data_pw("ntlmssp v2 sig ", sig->data, sig->length);

	} else {
		uint32 crc;
		crc = crc32_calc_buffer(data, length);
		if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmv1_seq_num)) {
			return NT_STATUS_NO_MEMORY;
		}
		
		ntlmssp_state->ntlmv1_seq_num++;

		dump_arc4_state("ntlmssp hash: \n", &ntlmssp_state->ntlmv1_arc4_state);
		arcfour_crypt_sbox(&ntlmssp_state->ntlmv1_arc4_state, sig->data+4, sig->length-4);
	}
	return NT_STATUS_OK;
}
Ejemplo n.º 30
0
NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
                             uchar *data, size_t length,
                             DATA_BLOB *sig)
{
    if (!ntlmssp_state->session_key.length) {
        DEBUG(3, ("NO session key, cannot seal packet\n"));
        return NT_STATUS_NO_USER_SESSION_KEY;
    }

    DEBUG(10,("ntlmssp_seal_data: seal\n"));
    dump_data_pw("ntlmssp clear data\n", data, length);
    if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
        HMACMD5Context ctx;
        char seq_num[4];
        uchar digest[16];
        SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);

        hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx);
        hmac_md5_update((const unsigned char *)seq_num, 4, &ctx);
        hmac_md5_update(data, length, &ctx);
        hmac_md5_final(digest, &ctx);

        if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */
                       , ntlmssp_state->ntlmssp_seq_num)) {
            return NT_STATUS_NO_MEMORY;
        }

        dump_data_pw("ntlmssp client sealing hash:\n",
                     ntlmssp_state->send_seal_hash,
                     sizeof(ntlmssp_state->send_seal_hash));
        NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length);
        dump_data_pw("ntlmssp client signing hash:\n",
                     ntlmssp_state->send_sign_hash,
                     sizeof(ntlmssp_state->send_sign_hash));
        NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash,  sig->data+4, sig->length-4);
    } else {
        uint32 crc;
        crc = crc32_calc_buffer((const char *)data, length);
        if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
            return NT_STATUS_NO_MEMORY;
        }

        /* The order of these two operations matters - we must first seal the packet,
           then seal the sequence number - this is becouse the ntlmssp_hash is not
           constant, but is is rather updated with each iteration */

        dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
                     sizeof(ntlmssp_state->ntlmssp_hash));
        NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length);

        dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
                     sizeof(ntlmssp_state->ntlmssp_hash));
        NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4);
    }
    dump_data_pw("ntlmssp sealed data\n", data, length);

    /* increment counter on send */
    ntlmssp_state->ntlmssp_seq_num++;

    return NT_STATUS_OK;
}