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); }
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; 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 = 0; buf->names[0].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); }
int setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp) { int rc; int baselen; unsigned int tilen; struct ntlmv2_resp *buf; char ntlmv2_hash[16]; unsigned char *tiblob = NULL; /* target info blob */ if (ses->server->secType == RawNTLMSSP) { if (!ses->domainName) { rc = find_domain_name(ses, nls_cp); if (rc) { cERROR(1, "error %d finding domain name", rc); goto setup_ntlmv2_rsp_ret; } } } else { rc = build_avpair_blob(ses, nls_cp); if (rc) { cERROR(1, "error %d building av pair blob", rc); goto setup_ntlmv2_rsp_ret; } } baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp); tilen = ses->auth_key.len; tiblob = ses->auth_key.response; ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL); if (!ses->auth_key.response) { rc = ENOMEM; ses->auth_key.len = 0; cERROR(1, "%s: Can't allocate auth blob", __func__); goto setup_ntlmv2_rsp_ret; } ses->auth_key.len += baselen; buf = (struct ntlmv2_resp *) (ses->auth_key.response + CIFS_SESS_KEY_SIZE); 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; memcpy(ses->auth_key.response + baselen, tiblob, tilen); /* calculate ntlmv2_hash */ rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp); if (rc) { cERROR(1, "could not get v2 hash rc %d", rc); goto setup_ntlmv2_rsp_ret; } /* calculate first part of the client response (CR1) */ rc = CalcNTLMv2_response(ses, ntlmv2_hash); if (rc) { cERROR(1, "Could not calculate CR1 rc: %d", rc); goto setup_ntlmv2_rsp_ret; } /* now calculate the session key for NTLMv2 */ crypto_shash_setkey(ses->server->secmech.hmacmd5, ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); if (rc) { cERROR(1, "%s: Could not init hmacmd5\n", __func__); goto setup_ntlmv2_rsp_ret; } crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, ses->auth_key.response + CIFS_SESS_KEY_SIZE, CIFS_HMAC_MD5_HASH_SIZE); rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, ses->auth_key.response); setup_ntlmv2_rsp_ret: kfree(tiblob); return rc; }
/** Initialise the state for NTLMSSP signing. */ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) { unsigned char p24[24]; ZERO_STRUCT(p24); DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); if (!ntlmssp_state->session_key.length) { DEBUG(3, ("NO session key, cannot intialise signing\n")); return NT_STATUS_NO_USER_SESSION_KEY; } if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { const char *send_sign_const; const char *send_seal_const; const char *recv_sign_const; const char *recv_seal_const; switch (ntlmssp_state->role) { case NTLMSSP_CLIENT: send_sign_const = CLI_SIGN; send_seal_const = CLI_SEAL; recv_sign_const = SRV_SIGN; recv_seal_const = SRV_SEAL; break; case NTLMSSP_SERVER: send_sign_const = SRV_SIGN; send_seal_const = SRV_SEAL; recv_sign_const = CLI_SIGN; recv_seal_const = CLI_SEAL; break; } calc_ntlmv2_hash(ntlmssp_state->send_sign_hash, ntlmssp_state->send_sign_const, ntlmssp_state->session_key, send_sign_const); dump_data_pw("NTLMSSP send sign hash:\n", ntlmssp_state->send_sign_hash, sizeof(ntlmssp_state->send_sign_hash)); calc_ntlmv2_hash(ntlmssp_state->send_seal_hash, ntlmssp_state->send_seal_const, ntlmssp_state->session_key, send_seal_const); dump_data_pw("NTLMSSP send sesl hash:\n", ntlmssp_state->send_seal_hash, sizeof(ntlmssp_state->send_seal_hash)); calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash, ntlmssp_state->recv_sign_const, ntlmssp_state->session_key, recv_sign_const); dump_data_pw("NTLMSSP receive sign hash:\n", ntlmssp_state->recv_sign_hash, sizeof(ntlmssp_state->recv_sign_hash)); calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash, ntlmssp_state->recv_seal_const, ntlmssp_state->session_key, recv_seal_const); dump_data_pw("NTLMSSP receive seal hash:\n", ntlmssp_state->recv_sign_hash, sizeof(ntlmssp_state->recv_sign_hash)); } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) { /* can't sign or check signatures yet */ DEBUG(5, ("NTLMSSP Sign/Seal - cannot use LM KEY yet\n")); return NT_STATUS_UNSUCCESSFUL; } DEBUG(5, ("NTLMSSP Sign/Seal - using LM KEY\n")); calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 8); dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); } else { if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 16) { /* can't sign or check signatures yet */ DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY yet\n")); return NT_STATUS_UNSUCCESSFUL; } DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n")); calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 16); dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); } ntlmssp_state->ntlmssp_seq_num = 0; return NT_STATUS_OK; }