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);
}
示例#2
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;

	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);
}
示例#3
0
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;
}
示例#4
0
/* Build a proper attribute value/target info pairs blob.
 * Fill in netbios and dns domain name and workstation name
 * and client time (total five av pairs and + one end of fields indicator.
 * Allocate domain name which gets freed when session struct is deallocated.
 */
static int
build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
{
	unsigned int dlen;
	unsigned int wlen;
	unsigned int size = 6 * sizeof(struct ntlmssp2_name);
	__le64  curtime;
	char *defdmname = "WORKGROUP";
	unsigned char *blobptr;
	struct ntlmssp2_name *attrptr;

	if (!ses->domainName) {
		ses->domainName = kstrdup(defdmname, GFP_KERNEL);
		if (!ses->domainName)
			return -ENOMEM;
	}

	dlen = strlen(ses->domainName);
	wlen = strlen(ses->server->hostname);

	/* The length of this blob is a size which is
	 * six times the size of a structure which holds name/size +
	 * two times the unicode length of a domain name +
	 * two times the unicode length of a server name +
	 * size of a timestamp (which is 8 bytes).
	 */
	ses->auth_key.len = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8;
	ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
	if (!ses->auth_key.response) {
		ses->auth_key.len = 0;
		cERROR(1, "Challenge target info allocation failure");
		return -ENOMEM;
	}

	blobptr = ses->auth_key.response;
	attrptr = (struct ntlmssp2_name *) blobptr;

	attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
	attrptr->length = cpu_to_le16(2 * dlen);
	blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
	cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);

	blobptr += 2 * dlen;
	attrptr = (struct ntlmssp2_name *) blobptr;

	attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_COMPUTER_NAME);
	attrptr->length = cpu_to_le16(2 * wlen);
	blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
	cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);

	blobptr += 2 * wlen;
	attrptr = (struct ntlmssp2_name *) blobptr;

	attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_DOMAIN_NAME);
	attrptr->length = cpu_to_le16(2 * dlen);
	blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
	cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);

	blobptr += 2 * dlen;
	attrptr = (struct ntlmssp2_name *) blobptr;

	attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_COMPUTER_NAME);
	attrptr->length = cpu_to_le16(2 * wlen);
	blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
	cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);

	blobptr += 2 * wlen;
	attrptr = (struct ntlmssp2_name *) blobptr;

	attrptr->type = cpu_to_le16(NTLMSSP_AV_TIMESTAMP);
	attrptr->length = cpu_to_le16(sizeof(__le64));
	blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
	curtime = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
	memcpy(blobptr, &curtime, sizeof(__le64));

	return 0;
}
示例#5
0
__le64 cnvrtDosCifsTm(__u16 date, __u16 time)
{
	return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time)));
}