diff mbox

Linux CIFS NTLMSSP mount failing against win2k8

Message ID 20100414113453.6a523b21@tlielax.poochiereds.net
State New
Headers show

Commit Message

Jeff Layton April 14, 2010, 3:34 p.m. UTC
On Wed, 14 Apr 2010 08:29:44 -0400
Jeff Layton <jlayton@samba.org> wrote:

> On Wed, 14 Apr 2010 09:01:32 +1000
> Andrew Bartlett <abartlet@samba.org> wrote:
> 
> > On Sun, 2010-04-11 at 19:40 -0400, Jeff Layton wrote:
> > 
> > > I don't think that's right. CIFS_SESS_KEY_SIZE is 24 bytes. According
> > > to the MS-NLMP document, the session key should be 16 bytes. The
> > > signing key is different with NTLMSSP than with "raw" NTLM and NTLMv2.
> > 
> > So, with NTLMSSP the 24 byte (actually variable, it is much lager for
> > NTLMv2) response is not included in the MAC calculation - just use the
> > 16 bytes session key only. 
> > 
> > Andrew Bartlett
> > 
> 
> That was it! I was putting the right key into the NTLMSSP response, but
> was leaving the saved key used for signing as a 40-byte key. When I
> limit the key length to 16 then signing works correctly.
> 
> I'll need to clean up the code a bit, but will post a patch to fix this
> soon.
> 
> Many thanks,

Sigh, I made a mistake in testing. This didn't actually fix the
problem. The tree connect is still rejected after session setup. The
odd thing here is that this mount works against my samba server
(samba-3.4.7-58.fc12.x86_64).

Anyway for the purposes of discussion, here is the current patch I've
got. Signing is still busted with this though. Anyone have thoughts on
what we're doing wrong here?

Comments

Jeff Layton April 17, 2010, 2:44 a.m. UTC | #1
On Wed, 14 Apr 2010 11:34:53 -0400
Jeff Layton <jlayton@samba.org> wrote:

> On Wed, 14 Apr 2010 08:29:44 -0400
> Jeff Layton <jlayton@samba.org> wrote:
> 
> > On Wed, 14 Apr 2010 09:01:32 +1000
> > Andrew Bartlett <abartlet@samba.org> wrote:
> > 
> > > On Sun, 2010-04-11 at 19:40 -0400, Jeff Layton wrote:
> > > 
> > > > I don't think that's right. CIFS_SESS_KEY_SIZE is 24 bytes. According
> > > > to the MS-NLMP document, the session key should be 16 bytes. The
> > > > signing key is different with NTLMSSP than with "raw" NTLM and NTLMv2.
> > > 
> > > So, with NTLMSSP the 24 byte (actually variable, it is much lager for
> > > NTLMv2) response is not included in the MAC calculation - just use the
> > > 16 bytes session key only. 
> > > 
> > > Andrew Bartlett
> > > 
> > 
> > That was it! I was putting the right key into the NTLMSSP response, but
> > was leaving the saved key used for signing as a 40-byte key. When I
> > limit the key length to 16 then signing works correctly.
> > 
> > I'll need to clean up the code a bit, but will post a patch to fix this
> > soon.
> > 
> > Many thanks,
> 
> Sigh, I made a mistake in testing. This didn't actually fix the
> problem. The tree connect is still rejected after session setup. The
> odd thing here is that this mount works against my samba server
> (samba-3.4.7-58.fc12.x86_64).
> 
> Anyway for the purposes of discussion, here is the current patch I've
> got. Signing is still busted with this though. Anyone have thoughts on
> what we're doing wrong here?
> 

An update on this...

I think I now understand what the problem is. Volker pointed me in the
right direction. There were several problems actually:

- the sequence number was wrong. With a 4-packet Session Setup
  exchange, the following tree connect should be sequence number 2. I
  hacked in a quick fix for that but it still didn't work...

- then I read the spec more carefully. The problem is that the existing
  code doesn't try to use NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
  (aka NTLM2 -- not to be confused with NTLMv2).

Without that, the server expects signatures done using rc4, but cifs
universally uses md5 signatures. So we need to negotiate with that flag
too. At this point, I don't have the time to undertake this project
(and it does seem to be a project), so I've left this code alone for
now. It may be quite some time before I can fix this. It would be great
if someone else could take on this project instead :)

There are a couple of other things that could stand to be fixed too:

- The client uses NTLMv1 auth in the exchange. It seems like it would
  be better to use NTLMv2 instead. Are there any known servers that
  support the NTLMSSP GSSAPI scheme but that don't support NTLMv2 auth?

- The code uses its own crypto routines. It would be preferable to have
  it use the kernel's crypto API where possible.

- being able to do SPNEGO-wrapped NTLMSSP instead of just "raw" would
  also be great.

Anyway, hopefully these notes will be helpful to whomever ends up
fixing this code.
Andrew Bartlett April 17, 2010, 5:58 a.m. UTC | #2
On Fri, 2010-04-16 at 22:44 -0400, Jeff Layton wrote:
> On Wed, 14 Apr 2010 11:34:53 -0400
> Jeff Layton <jlayton@samba.org> wrote:
> 
> > On Wed, 14 Apr 2010 08:29:44 -0400
> > Jeff Layton <jlayton@samba.org> wrote:
> > 
> > > On Wed, 14 Apr 2010 09:01:32 +1000
> > > Andrew Bartlett <abartlet@samba.org> wrote:
> > > 
> > > > On Sun, 2010-04-11 at 19:40 -0400, Jeff Layton wrote:
> > > > 
> > > > > I don't think that's right. CIFS_SESS_KEY_SIZE is 24 bytes. According
> > > > > to the MS-NLMP document, the session key should be 16 bytes. The
> > > > > signing key is different with NTLMSSP than with "raw" NTLM and NTLMv2.
> > > > 
> > > > So, with NTLMSSP the 24 byte (actually variable, it is much lager for
> > > > NTLMv2) response is not included in the MAC calculation - just use the
> > > > 16 bytes session key only. 
> > > > 
> > > > Andrew Bartlett
> > > > 
> > > 
> > > That was it! I was putting the right key into the NTLMSSP response, but
> > > was leaving the saved key used for signing as a 40-byte key. When I
> > > limit the key length to 16 then signing works correctly.
> > > 
> > > I'll need to clean up the code a bit, but will post a patch to fix this
> > > soon.
> > > 
> > > Many thanks,
> > 
> > Sigh, I made a mistake in testing. This didn't actually fix the
> > problem. The tree connect is still rejected after session setup. The
> > odd thing here is that this mount works against my samba server
> > (samba-3.4.7-58.fc12.x86_64).
> > 
> > Anyway for the purposes of discussion, here is the current patch I've
> > got. Signing is still busted with this though. Anyone have thoughts on
> > what we're doing wrong here?
> > 
> 
> An update on this...
> 
> I think I now understand what the problem is. Volker pointed me in the
> right direction. There were several problems actually:
> 
> - the sequence number was wrong. With a 4-packet Session Setup
>   exchange, the following tree connect should be sequence number 2. I
>   hacked in a quick fix for that but it still didn't work...

Yes, you do need to get the sequence number right. 

> - then I read the spec more carefully. The problem is that the existing
>   code doesn't try to use NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
>   (aka NTLM2 -- not to be confused with NTLMv2).
> 
> Without that, the server expects signatures done using rc4, but cifs
> universally uses md5 signatures. 

This isn't the case.  SMB signing is always MD5.  NTLM2 simply changes
the 'effective' challenge and the session key, by providing a value in
the 'LM hash' to include with the Negotiate-provided challenge.

> So we need to negotiate with that flag
> too. At this point, I don't have the time to undertake this project
> (and it does seem to be a project), so I've left this code alone for
> now. It may be quite some time before I can fix this. It would be great
> if someone else could take on this project instead :)
> 
> There are a couple of other things that could stand to be fixed too:
> 
> - The client uses NTLMv1 auth in the exchange. It seems like it would
>   be better to use NTLMv2 instead. Are there any known servers that
>   support the NTLMSSP GSSAPI scheme but that don't support NTLMv2 auth?

There are.  The compatibility for NTLMv2 is dependent entirely on the
domain controller, while 'NTLM2 session security' does not need
co-operation from the DC. 

However, all real world DCs now support NTLMv2, as long as you get the
workstation names right etc. 

> - The code uses its own crypto routines. It would be preferable to have
>   it use the kernel's crypto API where possible.
> 
> - being able to do SPNEGO-wrapped NTLMSSP instead of just "raw" would
>   also be great.
> 
> Anyway, hopefully these notes will be helpful to whomever ends up
> fixing this code.

I'm happy to help confuse you further if required ;-)

Andrew Bartlett
Jeff Layton April 17, 2010, 10:29 a.m. UTC | #3
On Sat, 17 Apr 2010 15:58:23 +1000
Andrew Bartlett <abartlet@samba.org> wrote:

> On Fri, 2010-04-16 at 22:44 -0400, Jeff Layton wrote:
> > 
> > - then I read the spec more carefully. The problem is that the existing
> >   code doesn't try to use NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
> >   (aka NTLM2 -- not to be confused with NTLMv2).
> > 
> > Without that, the server expects signatures done using rc4, but cifs
> > universally uses md5 signatures. 
> 
> This isn't the case.  SMB signing is always MD5.  NTLM2 simply changes
> the 'effective' challenge and the session key, by providing a value in
> the 'LM hash' to include with the Negotiate-provided challenge.
> 

Interesting. That seems to be contradictory to what the MS-NLMP
document says. If you have a look at section 3.4.4.1, you'll see that
the algorithm for computing the signature does not use md5. However if
you negotiate extended session security (aka NTLM2) or use NTLMv2, then
you're supposed to use md5. Perhaps we should bring that up on the
dochelp list?

In any case, I think the right solution is just to have CIFS always use
extended session security and NTLMv2.

> > So we need to negotiate with that flag
> > too. At this point, I don't have the time to undertake this project
> > (and it does seem to be a project), so I've left this code alone for
> > now. It may be quite some time before I can fix this. It would be great
> > if someone else could take on this project instead :)
> > 
> > There are a couple of other things that could stand to be fixed too:
> > 
> > - The client uses NTLMv1 auth in the exchange. It seems like it would
> >   be better to use NTLMv2 instead. Are there any known servers that
> >   support the NTLMSSP GSSAPI scheme but that don't support NTLMv2 auth?
> 
> There are.  The compatibility for NTLMv2 is dependent entirely on the
> domain controller, while 'NTLM2 session security' does not need
> co-operation from the DC. 
> 
> However, all real world DCs now support NTLMv2, as long as you get the
> workstation names right etc. 
> 
> > - The code uses its own crypto routines. It would be preferable to have
> >   it use the kernel's crypto API where possible.
> > 
> > - being able to do SPNEGO-wrapped NTLMSSP instead of just "raw" would
> >   also be great.
> > 
> > Anyway, hopefully these notes will be helpful to whomever ends up
> > fixing this code.
> 
> I'm happy to help confuse you further if required ;-)
> 

Thanks. This protocol is INSANE. I think we're going to have to
overhaul a lot of the CIFS crypto from the ground up in order to do
this right.
Steve French April 17, 2010, 1:50 p.m. UTC | #4
On Sat, Apr 17, 2010 at 5:29 AM, Jeff Layton <jlayton@samba.org> wrote:
> On Sat, 17 Apr 2010 15:58:23 +1000
> Andrew Bartlett <abartlet@samba.org> wrote:
>
>> On Fri, 2010-04-16 at 22:44 -0400, Jeff Layton wrote:
>> >
>> > - then I read the spec more carefully. The problem is that the existing
>> >   code doesn't try to use NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
>> >   (aka NTLM2 -- not to be confused with NTLMv2).
>> >
>> > Without that, the server expects signatures done using rc4, but cifs
>> > universally uses md5 signatures.
>>
>> This isn't the case.  SMB signing is always MD5.  NTLM2 simply changes
>> the 'effective' challenge and the session key, by providing a value in
>> the 'LM hash' to include with the Negotiate-provided challenge.
>>
>
> Interesting. That seems to be contradictory to what the MS-NLMP
> document says. If you have a look at section 3.4.4.1, you'll see that
> the algorithm for computing the signature does not use md5. However if
> you negotiate extended session security (aka NTLM2) or use NTLMv2, then
> you're supposed to use md5. Perhaps we should bring that up on the
> dochelp list?

Yes.

> In any case, I think the right solution is just to have CIFS always use
> extended session security and NTLMv2.

This is a good idea - I had been planning to rip the NTLM code
out of SMB2 (simplifies things, and SMB2 is only NTLMSSP or krb5/SPNEGO)
and this will probably make the code more consistent if we don't do
NTLM in NTLMSSP for cifs as well (although plenty of cifs servers don't
support NTLMv2 we probably would never have to use NTLMSSP to them)
Andrew Bartlett April 17, 2010, 9:51 p.m. UTC | #5
On Sat, 2010-04-17 at 08:50 -0500, Steve French wrote:
> On Sat, Apr 17, 2010 at 5:29 AM, Jeff Layton <jlayton@samba.org> wrote:

> > In any case, I think the right solution is just to have CIFS always use
> > extended session security and NTLMv2.
> 
> This is a good idea - I had been planning to rip the NTLM code
> out of SMB2 (simplifies things, and SMB2 is only NTLMSSP or krb5/SPNEGO)
> and this will probably make the code more consistent if we don't do
> NTLM in NTLMSSP for cifs as well (although plenty of cifs servers don't
> support NTLMv2 we probably would never have to use NTLMSSP to them)

I strongly encourage you not to do this.  You should always use NTLMSSP,
but I would always support at least NTLMSSP with NTLM2 to those servers.
It is much more secure than raw NTLM. 

You should do NTLMv2 by default, but it is far more fragile than the
older versions, and you will find incompatibilities. 

Andrew Bartlett
Shirish Pargaonkar April 21, 2010, 2:29 p.m. UTC | #6
On Sat, Apr 17, 2010 at 5:29 AM, Jeff Layton <jlayton@samba.org> wrote:
> On Sat, 17 Apr 2010 15:58:23 +1000
> Andrew Bartlett <abartlet@samba.org> wrote:
>
>> On Fri, 2010-04-16 at 22:44 -0400, Jeff Layton wrote:
>> >
>> > - then I read the spec more carefully. The problem is that the existing
>> >   code doesn't try to use NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
>> >   (aka NTLM2 -- not to be confused with NTLMv2).
>> >
>> > Without that, the server expects signatures done using rc4, but cifs
>> > universally uses md5 signatures.
>>
>> This isn't the case.  SMB signing is always MD5.  NTLM2 simply changes
>> the 'effective' challenge and the session key, by providing a value in
>> the 'LM hash' to include with the Negotiate-provided challenge.
>>
>
> Interesting. That seems to be contradictory to what the MS-NLMP
> document says. If you have a look at section 3.4.4.1, you'll see that
> the algorithm for computing the signature does not use md5. However if
> you negotiate extended session security (aka NTLM2) or use NTLMv2, then
> you're supposed to use md5. Perhaps we should bring that up on the
> dochelp list?
>

> In any case, I think the right solution is just to have CIFS always use
> extended session security and NTLMv2.

If by extended session security you mean NTLM2, are not NTLMv2 and
NTLM2 both authentication mechanisms and orthogonal to each other?
In which case, I think cifs/smb2 clients should at least make NTLMv2 auth mech
within NTLMSSP (Raw or SPNEGO) work against a Windows server
like Windows7/Vista/2008 server, with and without SMB signing.

NTLMv.2 in NTLMSSP will work with LMCompatibililtyLevel settings of
0 through 5.  I am not whether NTLM2 will work with with settings (eg. 4, 5)
and I am not sure whether NTLM2 needs/works_with SMB signing i.e.
how to calculate session key, mac key, signature etc.

>
>> > So we need to negotiate with that flag
>> > too. At this point, I don't have the time to undertake this project
>> > (and it does seem to be a project), so I've left this code alone for
>> > now. It may be quite some time before I can fix this. It would be great
>> > if someone else could take on this project instead :)
>> >
>> > There are a couple of other things that could stand to be fixed too:
>> >
>> > - The client uses NTLMv1 auth in the exchange. It seems like it would
>> >   be better to use NTLMv2 instead. Are there any known servers that
>> >   support the NTLMSSP GSSAPI scheme but that don't support NTLMv2 auth?
>>
>> There are.  The compatibility for NTLMv2 is dependent entirely on the
>> domain controller, while 'NTLM2 session security' does not need
>> co-operation from the DC.
>>
>> However, all real world DCs now support NTLMv2, as long as you get the
>> workstation names right etc.
>>
>> > - The code uses its own crypto routines. It would be preferable to have
>> >   it use the kernel's crypto API where possible.
>> >
>> > - being able to do SPNEGO-wrapped NTLMSSP instead of just "raw" would
>> >   also be great.
>> >
>> > Anyway, hopefully these notes will be helpful to whomever ends up
>> > fixing this code.
>>
>> I'm happy to help confuse you further if required ;-)
>>
>
> Thanks. This protocol is INSANE. I think we're going to have to
> overhaul a lot of the CIFS crypto from the ground up in order to do
> this right.
>
> --
> Jeff Layton <jlayton@samba.org>
>
Jeff Layton April 21, 2010, 8:19 p.m. UTC | #7
On Wed, 21 Apr 2010 09:29:33 -0500
Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:

> On Sat, Apr 17, 2010 at 5:29 AM, Jeff Layton <jlayton@samba.org> wrote:
> > On Sat, 17 Apr 2010 15:58:23 +1000
> > Andrew Bartlett <abartlet@samba.org> wrote:
> >
> >> On Fri, 2010-04-16 at 22:44 -0400, Jeff Layton wrote:
> >> >
> >> > - then I read the spec more carefully. The problem is that the existing
> >> >   code doesn't try to use NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
> >> >   (aka NTLM2 -- not to be confused with NTLMv2).
> >> >
> >> > Without that, the server expects signatures done using rc4, but cifs
> >> > universally uses md5 signatures.
> >>
> >> This isn't the case.  SMB signing is always MD5.  NTLM2 simply changes
> >> the 'effective' challenge and the session key, by providing a value in
> >> the 'LM hash' to include with the Negotiate-provided challenge.
> >>
> >
> > Interesting. That seems to be contradictory to what the MS-NLMP
> > document says. If you have a look at section 3.4.4.1, you'll see that
> > the algorithm for computing the signature does not use md5. However if
> > you negotiate extended session security (aka NTLM2) or use NTLMv2, then
> > you're supposed to use md5. Perhaps we should bring that up on the
> > dochelp list?
> >
> 
> > In any case, I think the right solution is just to have CIFS always use
> > extended session security and NTLMv2.
> 
> If by extended session security you mean NTLM2, are not NTLMv2 and
> NTLM2 both authentication mechanisms and orthogonal to each other?

I'd probably call them "mutually exclusive" rather than "orthogonal".
The NTLM2 flag is always supposed to be set if you're using NTLMv2, but
its presence doesn't mean you're using NTLMv2.

> In which case, I think cifs/smb2 clients should at least make NTLMv2 auth mech
> within NTLMSSP (Raw or SPNEGO) work against a Windows server
> like Windows7/Vista/2008 server, with and without SMB signing.
> 

Agreed, though we need to have some sort of way to automatically fall
back to NTLM2 if that doesn't work against the server.

> NTLMv.2 in NTLMSSP will work with LMCompatibililtyLevel settings of
> 0 through 5.  I am not whether NTLM2 will work with with settings (eg. 4, 5)
> and I am not sure whether NTLM2 needs/works_with SMB signing i.e.
> how to calculate session key, mac key, signature etc.
> 

I'll take your word for it. I've walked away from all of this for the
time being. I will say however that if you're doing some work for this
for SMB2, then please consider doing this in a fashion that will allow
the code to be shared with CIFS as well.
diff mbox

Patch

From d973ea60245837d2f501ef32f847b917e9bd69aa Mon Sep 17 00:00:00 2001
From: Jeff Layton <jlayton@redhat.com>
Date: Wed, 14 Apr 2010 10:46:00 -0400
Subject: [PATCH] cifs: fix MAC signatures when NTLMSSP auth is in use

The session key is not currently sent in the response and isn't calculated
properly. Also fix the flags so that keys are properly exchanged.

Finally, there's no need to put the NTLM response on the stack and then
copy it to the buffer. Just write it directly to the buffer in the first
place.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/cifs/cifsencrypt.c |   10 ++++++++++
 fs/cifs/cifspdu.h     |    3 +++
 fs/cifs/cifsproto.h   |    1 +
 fs/cifs/ntlmssp.h     |    3 +--
 fs/cifs/sess.c        |   32 +++++++++++++++-----------------
 5 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index fbe9864..5d69ac8 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -208,6 +208,16 @@  int cifs_verify_signature(struct smb_hdr *cifs_pdu,
 
 }
 
+void
+cifs_set_ntlmssp_key(struct mac_key *key, const char *password)
+{
+	char temp_key[CIFS_NTLMSSP_SIGN_KEY_SIZE];
+
+	E_md4hash(password, temp_key);
+	mdfour(key->data.ntlm, temp_key, CIFS_NTLMSSP_SIGN_KEY_SIZE);
+	key->len = CIFS_NTLMSSP_SIGN_KEY_SIZE;
+}
+
 /* We fill in key by putting in 40 byte array which was allocated by caller */
 int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
 			   const char *password)
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 14d036d..749e161 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -135,6 +135,9 @@ 
  */
 #define CIFS_SESS_KEY_SIZE (24)
 
+/* Size of signing key when NTLMSSP is in use. Size of md4 hash. */
+#define CIFS_NTLMSSP_SIGN_KEY_SIZE (16)
+
 /*
  * Maximum user name length
  */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 39e47f4..96f8c6f 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -346,6 +346,7 @@  extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
 extern int cifs_verify_signature(struct smb_hdr *,
 				 const struct mac_key *mac_key,
 				__u32 expected_sequence_number);
+extern void cifs_set_ntlmssp_key(struct mac_key *key, const char *password);
 extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
 				 const char *pass);
 extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *,
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 49c9a4e..6456aec 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -47,9 +47,8 @@ 
 #define NTLMSSP_TARGET_TYPE_SERVER     0x20000
 #define NTLMSSP_TARGET_TYPE_SHARE      0x40000
 #define NTLMSSP_NEGOTIATE_EXTENDED_SEC 0x80000 /* NB:not related to NTLMv2 pwd*/
-/* #define NTLMSSP_REQUEST_INIT_RESP     0x100000 */
 #define NTLMSSP_NEGOTIATE_IDENTIFY    0x100000
-#define NTLMSSP_REQUEST_ACCEPT_RESP   0x200000 /* reserved5 */
+/* #define reserved5		      0x200000 */
 #define NTLMSSP_REQUEST_NON_NT_KEY    0x400000
 #define NTLMSSP_NEGOTIATE_TARGET_INFO 0x800000
 /* #define reserved4                 0x1000000 */
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 7c3fd74..b2cb182 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -388,7 +388,7 @@  static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
 		return -EINVAL;
 	}
 
-	if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
+	if (memcmp(pblob->Signature, NTLMSSP_SIGNATURE, 8)) {
 		cERROR(1, ("blob signature incorrect %s", pblob->Signature));
 		return -EINVAL;
 	}
@@ -421,14 +421,12 @@  static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
 	sec_blob->MessageType = NtLmNegotiate;
 
 	/* BB is NTLMV2 session security format easier to use here? */
-	flags = NTLMSSP_NEGOTIATE_56 |	NTLMSSP_REQUEST_TARGET |
+	flags = NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_KEY_XCH |
 		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
 		NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM;
 	if (ses->server->secMode &
 	   (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
 		flags |= NTLMSSP_NEGOTIATE_SIGN;
-	if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
-		flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
 
 	sec_blob->NegotiateFlags |= cpu_to_le32(flags);
 
@@ -452,20 +450,16 @@  static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
 	AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
 	__u32 flags;
 	unsigned char *tmp;
-	char ntlm_session_key[CIFS_SESS_KEY_SIZE];
 
 	memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
 	sec_blob->MessageType = NtLmAuthenticate;
 
-	flags = NTLMSSP_NEGOTIATE_56 |
-		NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
+	flags = NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_KEY_XCH |
 		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
 		NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM;
 	if (ses->server->secMode &
 	   (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
 		flags |= NTLMSSP_NEGOTIATE_SIGN;
-	if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
-		flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
 
 	tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
 	sec_blob->NegotiateFlags |= cpu_to_le32(flags);
@@ -476,17 +470,16 @@  static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
 	sec_blob->LmChallengeResponse.MaximumLength = 0;
 
 	/* calculate session key,  BB what about adding similar ntlmv2 path? */
-	SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key);
-	if (first)
-		cifs_calculate_mac_key(&ses->server->mac_signing_key,
-				       ntlm_session_key, ses->password);
-
-	memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE);
+	SMBNTencrypt(ses->password, ses->server->cryptKey, tmp);
 	sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
 	sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE);
 	sec_blob->NtChallengeResponse.MaximumLength =
 				cpu_to_le16(CIFS_SESS_KEY_SIZE);
 
+	if (first)
+		cifs_set_ntlmssp_key(&ses->server->mac_signing_key,
+				     ses->password);
+
 	tmp += CIFS_SESS_KEY_SIZE;
 
 	if (ses->domainName == NULL) {
@@ -528,9 +521,14 @@  static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
 	sec_blob->WorkstationName.MaximumLength = 0;
 	tmp += 2;
 
+	memcpy(tmp, &ses->server->mac_signing_key.data.ntlm,
+		CIFS_NTLMSSP_SIGN_KEY_SIZE);
 	sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
-	sec_blob->SessionKey.Length = 0;
-	sec_blob->SessionKey.MaximumLength = 0;
+	sec_blob->SessionKey.Length = cpu_to_le16(CIFS_NTLMSSP_SIGN_KEY_SIZE);
+	sec_blob->SessionKey.MaximumLength =
+				cpu_to_le16(CIFS_NTLMSSP_SIGN_KEY_SIZE);
+	tmp += CIFS_NTLMSSP_SIGN_KEY_SIZE;
+
 	return tmp - pbuffer;
 }
 
-- 
1.6.6.1