Commit 2c957ddf authored by Tim Gardner's avatar Tim Gardner Committed by Steve French

cifs: Use data structures to compute NTLMv2 response offsets

A bit of cleanup plus some gratuitous variable renaming. I think using
structures instead of numeric offsets makes this code much more
understandable.

Also added a comment about current time range expected by
the server.
Acked-by: default avatarJeff Layton <jlayton@redhat.com>
Reviewed-by: default avatarShirish Pargaonkar <spargaonkar@suse.com>
Signed-off-by: default avatarTim Gardner <tim.gardner@canonical.com>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent dca69288
...@@ -548,7 +548,13 @@ static int ...@@ -548,7 +548,13 @@ static int
CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
{ {
int rc; int rc;
unsigned int offset = CIFS_SESS_KEY_SIZE + 8; struct ntlmv2_resp *ntlmv2 = (struct ntlmv2_resp *)
(ses->auth_key.response + CIFS_SESS_KEY_SIZE);
unsigned int hash_len;
/* The MD5 hash starts at challenge_key.key */
hash_len = ses->auth_key.len - (CIFS_SESS_KEY_SIZE +
offsetof(struct ntlmv2_resp, challenge.key[0]));
if (!ses->server->secmech.sdeschmacmd5) { if (!ses->server->secmech.sdeschmacmd5) {
cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__); cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__);
...@@ -556,7 +562,7 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) ...@@ -556,7 +562,7 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
} }
rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
if (rc) { if (rc) {
cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n", cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
__func__); __func__);
...@@ -570,20 +576,21 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) ...@@ -570,20 +576,21 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
} }
if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED)
memcpy(ses->auth_key.response + offset, memcpy(ntlmv2->challenge.key,
ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
else else
memcpy(ses->auth_key.response + offset, memcpy(ntlmv2->challenge.key,
ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
ses->auth_key.response + offset, ses->auth_key.len - offset); ntlmv2->challenge.key, hash_len);
if (rc) { if (rc) {
cifs_dbg(VFS, "%s: Could not update with response\n", __func__); cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
return rc; return rc;
} }
/* Note that the MD5 digest over writes anon.challenge_key.key */
rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
ses->auth_key.response + CIFS_SESS_KEY_SIZE); ntlmv2->ntlmv2_hash);
if (rc) if (rc)
cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
...@@ -627,7 +634,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) ...@@ -627,7 +634,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
int rc; int rc;
int baselen; int baselen;
unsigned int tilen; unsigned int tilen;
struct ntlmv2_resp *buf; struct ntlmv2_resp *ntlmv2;
char ntlmv2_hash[16]; char ntlmv2_hash[16];
unsigned char *tiblob = NULL; /* target info blob */ unsigned char *tiblob = NULL; /* target info blob */
...@@ -660,13 +667,14 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) ...@@ -660,13 +667,14 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
} }
ses->auth_key.len += baselen; ses->auth_key.len += baselen;
buf = (struct ntlmv2_resp *) ntlmv2 = (struct ntlmv2_resp *)
(ses->auth_key.response + CIFS_SESS_KEY_SIZE); (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
buf->blob_signature = cpu_to_le32(0x00000101); ntlmv2->blob_signature = cpu_to_le32(0x00000101);
buf->reserved = 0; ntlmv2->reserved = 0;
buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); /* Must be within 5 minutes of the server */
get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); ntlmv2->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
buf->reserved2 = 0; get_random_bytes(&ntlmv2->client_chal, sizeof(ntlmv2->client_chal));
ntlmv2->reserved2 = 0;
memcpy(ses->auth_key.response + baselen, tiblob, tilen); memcpy(ses->auth_key.response + baselen, tiblob, tilen);
...@@ -706,7 +714,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) ...@@ -706,7 +714,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
} }
rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
ses->auth_key.response + CIFS_SESS_KEY_SIZE, ntlmv2->ntlmv2_hash,
CIFS_HMAC_MD5_HASH_SIZE); CIFS_HMAC_MD5_HASH_SIZE);
if (rc) { if (rc) {
cifs_dbg(VFS, "%s: Could not update with response\n", __func__); cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
......
...@@ -697,7 +697,13 @@ struct ntlmssp2_name { ...@@ -697,7 +697,13 @@ struct ntlmssp2_name {
} __attribute__((packed)); } __attribute__((packed));
struct ntlmv2_resp { struct ntlmv2_resp {
char ntlmv2_hash[CIFS_ENCPWD_SIZE]; union {
char ntlmv2_hash[CIFS_ENCPWD_SIZE];
struct {
__u8 reserved[8];
__u8 key[CIFS_SERVER_CHALLENGE_SIZE];
} __attribute__((packed)) challenge;
} __attribute__((packed));
__le32 blob_signature; __le32 blob_signature;
__u32 reserved; __u32 reserved;
__le64 time; __le64 time;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment