2 * Copyright 2006 Kai Blin
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file contains various helper functions needed for NTLM and maybe others
26 #include "secur32_priv.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(ntlm
);
31 static const char client_to_server_sign_constant
[] = "session key to client-to-server signing key magic constant";
32 static const char client_to_server_seal_constant
[] = "session key to client-to-server sealing key magic constant";
33 static const char server_to_client_sign_constant
[] = "session key to server-to-client signing key magic constant";
34 static const char server_to_client_seal_constant
[] = "session key to server-to-client sealing key magic constant";
41 unsigned char digest
[16];
44 /* And now the same with a different memory layout. */
50 unsigned char digest
[16];
53 VOID WINAPI
MD4Init( MD4_CTX
*ctx
);
54 VOID WINAPI
MD4Update( MD4_CTX
*ctx
, const unsigned char *buf
, unsigned int len
);
55 VOID WINAPI
MD4Final( MD4_CTX
*ctx
);
56 VOID WINAPI
MD5Init( MD5_CTX
*ctx
);
57 VOID WINAPI
MD5Update( MD5_CTX
*ctx
, const unsigned char *buf
, unsigned int len
);
58 VOID WINAPI
MD5Final( MD5_CTX
*ctx
);
60 SECURITY_STATUS
SECUR32_CreateNTLM1SessionKey(PBYTE password
, int len
, PBYTE session_key
)
65 TRACE("(%p, %p)\n", password
, session_key
);
68 MD4Update(&ctx
, password
, len
);
71 memcpy(ntlm_hash
, ctx
.digest
, 0x10);
74 MD4Update(&ctx
, ntlm_hash
, 0x10u
);
77 memcpy(session_key
, ctx
.digest
, 0x10);
82 static void SECUR32_CalcNTLM2Subkey(const BYTE
*session_key
, const char *magic
, PBYTE subkey
)
87 MD5Update(&ctx
, session_key
, 16);
88 MD5Update(&ctx
, (const unsigned char*)magic
, lstrlenA(magic
)+1);
90 memcpy(subkey
, ctx
.digest
, 16);
93 /* This assumes we do have a valid NTLM2 user session key */
94 SECURITY_STATUS
SECUR32_CreateNTLM2SubKeys(PNegoHelper helper
)
96 helper
->crypt
.ntlm2
.send_sign_key
= heap_alloc(16);
97 helper
->crypt
.ntlm2
.send_seal_key
= heap_alloc(16);
98 helper
->crypt
.ntlm2
.recv_sign_key
= heap_alloc(16);
99 helper
->crypt
.ntlm2
.recv_seal_key
= heap_alloc(16);
101 if(helper
->mode
== NTLM_CLIENT
)
103 SECUR32_CalcNTLM2Subkey(helper
->session_key
, client_to_server_sign_constant
,
104 helper
->crypt
.ntlm2
.send_sign_key
);
105 SECUR32_CalcNTLM2Subkey(helper
->session_key
, client_to_server_seal_constant
,
106 helper
->crypt
.ntlm2
.send_seal_key
);
107 SECUR32_CalcNTLM2Subkey(helper
->session_key
, server_to_client_sign_constant
,
108 helper
->crypt
.ntlm2
.recv_sign_key
);
109 SECUR32_CalcNTLM2Subkey(helper
->session_key
, server_to_client_seal_constant
,
110 helper
->crypt
.ntlm2
.recv_seal_key
);
114 SECUR32_CalcNTLM2Subkey(helper
->session_key
, server_to_client_sign_constant
,
115 helper
->crypt
.ntlm2
.send_sign_key
);
116 SECUR32_CalcNTLM2Subkey(helper
->session_key
, server_to_client_seal_constant
,
117 helper
->crypt
.ntlm2
.send_seal_key
);
118 SECUR32_CalcNTLM2Subkey(helper
->session_key
, client_to_server_sign_constant
,
119 helper
->crypt
.ntlm2
.recv_sign_key
);
120 SECUR32_CalcNTLM2Subkey(helper
->session_key
, client_to_server_seal_constant
,
121 helper
->crypt
.ntlm2
.recv_seal_key
);
127 arc4_info
*SECUR32_arc4Alloc(void)
129 arc4_info
*a4i
= heap_alloc(sizeof(arc4_info
));
134 * The arc4 code is based on dlls/advapi32/crypt_arc4.c by Mike McCormack,
135 * which in turn is based on public domain code by Wei Dai
137 void SECUR32_arc4Init(arc4_info
*a4i
, const BYTE
*key
, unsigned int keyLen
)
139 unsigned int keyIndex
= 0, stateIndex
= 0;
142 TRACE("(%p, %p, %d)\n", a4i
, key
, keyLen
);
146 for (i
=0; i
<256; i
++)
149 for (i
=0; i
<256; i
++)
152 stateIndex
+= key
[keyIndex
] + a
;
154 a4i
->state
[i
] = a4i
->state
[stateIndex
];
155 a4i
->state
[stateIndex
] = a
;
156 if (++keyIndex
>= keyLen
)
162 void SECUR32_arc4Process(arc4_info
*a4i
, BYTE
*inoutString
, unsigned int length
)
164 BYTE
*const s
=a4i
->state
;
165 unsigned int x
= a4i
->x
;
166 unsigned int y
= a4i
->y
;
177 *inoutString
++ ^= s
[(a
+b
) & 0xff];
184 void SECUR32_arc4Cleanup(arc4_info
*a4i
)