diff options
author | Tim Gardner <tim.gardner@canonical.com> | 2013-11-07 18:40:57 -0500 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-11-11 17:58:11 -0500 |
commit | 2c957ddf30897787e39462ac56cdc4bf21eb0465 (patch) | |
tree | 5f968d8209f1a3546439a9ca5e46ee877a83df21 /fs | |
parent | dca692880e887739a669f6c41a80ca68ce2b09fc (diff) |
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: Jeff Layton <jlayton@redhat.com>
Reviewed-by: Shirish Pargaonkar <spargaonkar@suse.com>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/cifsencrypt.c | 40 | ||||
-rw-r--r-- | fs/cifs/cifspdu.h | 8 |
2 files changed, 31 insertions, 17 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index fc6f4f3a1a9d..4934347321d3 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -548,7 +548,13 @@ static int | |||
548 | CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) | 548 | CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) |
549 | { | 549 | { |
550 | int rc; | 550 | int rc; |
551 | unsigned int offset = CIFS_SESS_KEY_SIZE + 8; | 551 | struct ntlmv2_resp *ntlmv2 = (struct ntlmv2_resp *) |
552 | (ses->auth_key.response + CIFS_SESS_KEY_SIZE); | ||
553 | unsigned int hash_len; | ||
554 | |||
555 | /* The MD5 hash starts at challenge_key.key */ | ||
556 | hash_len = ses->auth_key.len - (CIFS_SESS_KEY_SIZE + | ||
557 | offsetof(struct ntlmv2_resp, challenge.key[0])); | ||
552 | 558 | ||
553 | if (!ses->server->secmech.sdeschmacmd5) { | 559 | if (!ses->server->secmech.sdeschmacmd5) { |
554 | cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__); | 560 | 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 | } | 562 | } |
557 | 563 | ||
558 | rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, | 564 | rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, |
559 | ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); | 565 | ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); |
560 | if (rc) { | 566 | if (rc) { |
561 | cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n", | 567 | cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n", |
562 | __func__); | 568 | __func__); |
@@ -570,20 +576,21 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) | |||
570 | } | 576 | } |
571 | 577 | ||
572 | if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) | 578 | if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) |
573 | memcpy(ses->auth_key.response + offset, | 579 | memcpy(ntlmv2->challenge.key, |
574 | ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); | 580 | ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); |
575 | else | 581 | else |
576 | memcpy(ses->auth_key.response + offset, | 582 | memcpy(ntlmv2->challenge.key, |
577 | ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); | 583 | ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); |
578 | rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, | 584 | rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, |
579 | ses->auth_key.response + offset, ses->auth_key.len - offset); | 585 | ntlmv2->challenge.key, hash_len); |
580 | if (rc) { | 586 | if (rc) { |
581 | cifs_dbg(VFS, "%s: Could not update with response\n", __func__); | 587 | cifs_dbg(VFS, "%s: Could not update with response\n", __func__); |
582 | return rc; | 588 | return rc; |
583 | } | 589 | } |
584 | 590 | ||
591 | /* Note that the MD5 digest over writes anon.challenge_key.key */ | ||
585 | rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, | 592 | rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, |
586 | ses->auth_key.response + CIFS_SESS_KEY_SIZE); | 593 | ntlmv2->ntlmv2_hash); |
587 | if (rc) | 594 | if (rc) |
588 | cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); | 595 | cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); |
589 | 596 | ||
@@ -627,7 +634,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) | |||
627 | int rc; | 634 | int rc; |
628 | int baselen; | 635 | int baselen; |
629 | unsigned int tilen; | 636 | unsigned int tilen; |
630 | struct ntlmv2_resp *buf; | 637 | struct ntlmv2_resp *ntlmv2; |
631 | char ntlmv2_hash[16]; | 638 | char ntlmv2_hash[16]; |
632 | unsigned char *tiblob = NULL; /* target info blob */ | 639 | unsigned char *tiblob = NULL; /* target info blob */ |
633 | 640 | ||
@@ -660,13 +667,14 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) | |||
660 | } | 667 | } |
661 | ses->auth_key.len += baselen; | 668 | ses->auth_key.len += baselen; |
662 | 669 | ||
663 | buf = (struct ntlmv2_resp *) | 670 | ntlmv2 = (struct ntlmv2_resp *) |
664 | (ses->auth_key.response + CIFS_SESS_KEY_SIZE); | 671 | (ses->auth_key.response + CIFS_SESS_KEY_SIZE); |
665 | buf->blob_signature = cpu_to_le32(0x00000101); | 672 | ntlmv2->blob_signature = cpu_to_le32(0x00000101); |
666 | buf->reserved = 0; | 673 | ntlmv2->reserved = 0; |
667 | buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); | 674 | /* Must be within 5 minutes of the server */ |
668 | get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); | 675 | ntlmv2->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); |
669 | buf->reserved2 = 0; | 676 | get_random_bytes(&ntlmv2->client_chal, sizeof(ntlmv2->client_chal)); |
677 | ntlmv2->reserved2 = 0; | ||
670 | 678 | ||
671 | memcpy(ses->auth_key.response + baselen, tiblob, tilen); | 679 | memcpy(ses->auth_key.response + baselen, tiblob, tilen); |
672 | 680 | ||
@@ -706,7 +714,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) | |||
706 | } | 714 | } |
707 | 715 | ||
708 | rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, | 716 | rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, |
709 | ses->auth_key.response + CIFS_SESS_KEY_SIZE, | 717 | ntlmv2->ntlmv2_hash, |
710 | CIFS_HMAC_MD5_HASH_SIZE); | 718 | CIFS_HMAC_MD5_HASH_SIZE); |
711 | if (rc) { | 719 | if (rc) { |
712 | cifs_dbg(VFS, "%s: Could not update with response\n", __func__); | 720 | cifs_dbg(VFS, "%s: Could not update with response\n", __func__); |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 9e5ee34de986..33df36ef9d52 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -697,7 +697,13 @@ struct ntlmssp2_name { | |||
697 | } __attribute__((packed)); | 697 | } __attribute__((packed)); |
698 | 698 | ||
699 | struct ntlmv2_resp { | 699 | struct ntlmv2_resp { |
700 | char ntlmv2_hash[CIFS_ENCPWD_SIZE]; | 700 | union { |
701 | char ntlmv2_hash[CIFS_ENCPWD_SIZE]; | ||
702 | struct { | ||
703 | __u8 reserved[8]; | ||
704 | __u8 key[CIFS_SERVER_CHALLENGE_SIZE]; | ||
705 | } __attribute__((packed)) challenge; | ||
706 | } __attribute__((packed)); | ||
701 | __le32 blob_signature; | 707 | __le32 blob_signature; |
702 | __u32 reserved; | 708 | __u32 reserved; |
703 | __le64 time; | 709 | __le64 time; |