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; }