2 * Unix SMB/CIFS implementation.
4 * NTLMSSP Signing routines
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2001
6 * Copyright (C) Andrew Bartlett 2003
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #define CLI_SIGN "session key to client-to-server signing key magic constant"
26 #define CLI_SEAL "session key to client-to-server sealing key magic constant"
27 #define SRV_SIGN "session key to server-to-client signing key magic constant"
28 #define SRV_SEAL "session key to server-to-client sealing key magic constant"
30 static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len)
32 unsigned char index_i = hash[256];
33 unsigned char index_j = hash[257];
36 for (ind = 0; ind < len; ind++)
42 index_j += hash[index_i];
45 hash[index_i] = hash[index_j];
48 t = hash[index_i] + hash[index_j];
49 data[ind] = data[ind] ^ hash[t];
56 static void calc_hash(unsigned char hash[258], const char *key, size_t key_len)
61 for (ind = 0; ind < 256; ind++)
63 hash[ind] = (unsigned char)ind;
66 for (ind = 0; ind < 256; ind++)
70 j += (hash[ind] + key[ind%key_len]);
82 * Some notes on then NTLM2 code:
84 * This code works correctly for the sealing part of the problem. If
85 * we disable the check for valid client signatures, then we see that
86 * the output of a rpcecho 'sinkdata' at smbd is correct. We get the
87 * valid data, and it is validly decrypted.
89 * This means that the quantity of data passing though the RC4 sealing
92 * This code also correctly matches test values that I have obtained,
93 * claiming to be the correct output of NTLM2 signature generation.
100 static void calc_ntlmv2_hash(unsigned char hash[258], unsigned char subkey[16],
101 DATA_BLOB session_key,
102 const char *constant)
104 struct MD5Context ctx3;
107 MD5Update(&ctx3, session_key.data, session_key.length);
108 MD5Update(&ctx3, constant, strlen(constant)+1);
109 MD5Final(subkey, &ctx3);
111 calc_hash(hash, subkey, 16);
114 enum ntlmssp_direction {
119 static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state,
120 TALLOC_CTX *sig_mem_ctx,
121 const uchar *data, size_t length,
122 enum ntlmssp_direction direction,
125 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
130 SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
134 hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key,
135 sizeof(ntlmssp_state->send_sign_key), &ctx);
137 case NTLMSSP_RECEIVE:
138 hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key,
139 sizeof(ntlmssp_state->recv_sign_key), &ctx);
142 hmac_md5_update(seq_num, 4, &ctx);
143 hmac_md5_update(data, length, &ctx);
144 hmac_md5_final(digest, &ctx);
146 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
149 NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, digest, 8);
151 case NTLMSSP_RECEIVE:
152 NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, digest, 8);
156 *sig = data_blob_talloc(sig_mem_ctx, NULL, 16);
157 SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION);
158 memcpy(sig->data + 4, digest, 8);
159 memcpy(sig->data + 12, seq_num, 4);
163 crc = crc32_calc_buffer((const char *)data, length);
164 if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
165 return NT_STATUS_NO_MEMORY;
168 dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
169 sizeof(ntlmssp_state->ntlmssp_hash));
170 NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4);
175 NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state,
176 TALLOC_CTX *sig_mem_ctx,
177 const uchar *data, size_t length,
182 if (!ntlmssp_state->session_key.length) {
183 DEBUG(3, ("NO session key, cannot check sign packet\n"));
184 return NT_STATUS_NO_USER_SESSION_KEY;
187 nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx,
188 data, length, NTLMSSP_SEND, sig);
190 /* increment counter on send */
191 ntlmssp_state->ntlmssp_seq_num++;
196 * Check the signature of an incoming packet
200 NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
201 TALLOC_CTX *sig_mem_ctx,
202 const uchar *data, size_t length,
203 const DATA_BLOB *sig)
208 if (!ntlmssp_state->session_key.length) {
209 DEBUG(3, ("NO session key, cannot check packet signature\n"));
210 return NT_STATUS_NO_USER_SESSION_KEY;
213 if (sig->length < 8) {
214 DEBUG(0, ("NTLMSSP packet check failed due to short signature (%lu bytes)!\n",
215 (unsigned long)sig->length));
218 nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx, data,
219 length, NTLMSSP_RECEIVE, &local_sig);
221 if (!NT_STATUS_IS_OK(nt_status)) {
222 DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status)));
226 /* increment counter on recv */
227 ntlmssp_state->ntlmssp_seq_num++;
229 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
230 if (local_sig.length != sig->length ||
231 memcmp(local_sig.data,
232 sig->data, sig->length) != 0) {
233 DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n"));
234 dump_data(5, local_sig.data, local_sig.length);
236 DEBUG(5, ("BAD SIG: got signature of\n"));
237 dump_data(5, sig->data, sig->length);
239 DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n"));
240 return NT_STATUS_ACCESS_DENIED;
243 if (local_sig.length != sig->length ||
244 memcmp(local_sig.data + 8,
245 sig->data + 8, sig->length - 8) != 0) {
246 DEBUG(5, ("BAD SIG NTLM1: wanted signature of\n"));
247 dump_data(5, (const char *)local_sig.data, local_sig.length);
249 DEBUG(5, ("BAD SIG: got signature of\n"));
250 dump_data(5, (const char *)(sig->data), sig->length);
252 DEBUG(0, ("NTLMSSP NTLM1 packet check failed due to invalid signature!\n"));
253 return NT_STATUS_ACCESS_DENIED;
262 * Seal data with the NTLMSSP algorithm
266 NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
267 TALLOC_CTX *sig_mem_ctx,
268 uchar *data, size_t length,
271 if (!ntlmssp_state->session_key.length) {
272 DEBUG(3, ("NO session key, cannot seal packet\n"));
273 return NT_STATUS_NO_USER_SESSION_KEY;
276 DEBUG(10,("ntlmssp_seal_data: seal\n"));
277 dump_data_pw("ntlmssp clear data\n", data, length);
278 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
282 SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
284 hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key,
285 sizeof(ntlmssp_state->send_sign_key), &ctx);
286 hmac_md5_update(seq_num, 4, &ctx);
287 hmac_md5_update(data, length, &ctx);
288 hmac_md5_final(digest, &ctx);
290 /* The order of these two operations matters - we must first seal the packet,
291 then seal the sequence number - this is becouse the send_seal_hash is not
292 constant, but is is rather updated with each iteration */
294 NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length);
296 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
297 NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, digest, 8);
300 *sig = data_blob_talloc(sig_mem_ctx, NULL, 16);
301 SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION);
302 memcpy(sig->data + 4, digest, 8);
303 memcpy(sig->data + 12, seq_num, 4);
306 crc = crc32_calc_buffer((const char *)data, length);
307 if (!msrpc_gen(sig_mem_ctx, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
308 return NT_STATUS_NO_MEMORY;
311 /* The order of these two operations matters - we must first seal the packet,
312 then seal the sequence number - this is becouse the ntlmssp_hash is not
313 constant, but is is rather updated with each iteration */
315 dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
316 sizeof(ntlmssp_state->ntlmssp_hash));
317 NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length);
319 dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
320 sizeof(ntlmssp_state->ntlmssp_hash));
321 NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4);
323 dump_data_pw("ntlmssp sealed data\n", data, length);
325 /* increment counter on send */
326 ntlmssp_state->ntlmssp_seq_num++;
332 * Unseal data with the NTLMSSP algorithm
336 NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state,
337 TALLOC_CTX *sig_mem_ctx,
338 uchar *data, size_t length,
341 if (!ntlmssp_state->session_key.length) {
342 DEBUG(3, ("NO session key, cannot unseal packet\n"));
343 return NT_STATUS_NO_USER_SESSION_KEY;
346 DEBUG(10,("ntlmssp__unseal_data: seal\n"));
347 dump_data_pw("ntlmssp sealed data\n", data, length);
348 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
349 NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, data, length);
351 dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
352 sizeof(ntlmssp_state->ntlmssp_hash));
353 NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length);
355 dump_data_pw("ntlmssp clear data\n", data, length);
357 return ntlmssp_check_packet(ntlmssp_state, sig_mem_ctx, data, length, sig);
359 /* increment counter on recv */
360 ntlmssp_state->ntlmssp_seq_num++;
364 Initialise the state for NTLMSSP signing.
366 NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state)
368 unsigned char p24[24];
371 DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n"));
372 debug_ntlmssp_flags(ntlmssp_state->neg_flags);
374 if (!ntlmssp_state->session_key.length) {
375 DEBUG(3, ("NO session key, cannot intialise signing\n"));
376 return NT_STATUS_NO_USER_SESSION_KEY;
379 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
381 const char *send_sign_const;
382 const char *send_seal_const;
383 const char *recv_sign_const;
384 const char *recv_seal_const;
386 switch (ntlmssp_state->role) {
388 send_sign_const = CLI_SIGN;
389 send_seal_const = CLI_SEAL;
390 recv_sign_const = SRV_SIGN;
391 recv_seal_const = SRV_SEAL;
394 send_sign_const = SRV_SIGN;
395 send_seal_const = SRV_SEAL;
396 recv_sign_const = CLI_SIGN;
397 recv_seal_const = CLI_SEAL;
402 calc_ntlmv2_hash(ntlmssp_state->send_sign_hash,
403 ntlmssp_state->send_sign_key,
404 ntlmssp_state->session_key, send_sign_const);
405 dump_data_pw("NTLMSSP send sign key:\n",
406 ntlmssp_state->send_sign_key,
407 sizeof(ntlmssp_state->send_sign_key));
409 dump_data_pw("NTLMSSP send sign hash:\n",
410 ntlmssp_state->send_sign_hash,
411 sizeof(ntlmssp_state->send_sign_hash));
413 calc_ntlmv2_hash(ntlmssp_state->send_seal_hash,
414 ntlmssp_state->send_seal_key,
415 ntlmssp_state->session_key, send_seal_const);
416 dump_data_pw("NTLMSSP send seal key:\n",
417 ntlmssp_state->send_seal_key,
418 sizeof(ntlmssp_state->send_seal_key));
420 dump_data_pw("NTLMSSP send sesl hash:\n",
421 ntlmssp_state->send_seal_hash,
422 sizeof(ntlmssp_state->send_seal_hash));
425 calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash,
426 ntlmssp_state->recv_sign_key,
427 ntlmssp_state->session_key, recv_sign_const);
428 dump_data_pw("NTLMSSP recv sign key:\n",
429 ntlmssp_state->recv_sign_key,
430 sizeof(ntlmssp_state->recv_sign_key));
431 dump_data_pw("NTLMSSP receive sign hash:\n",
432 ntlmssp_state->recv_sign_hash,
433 sizeof(ntlmssp_state->recv_sign_hash));
435 calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash,
436 ntlmssp_state->recv_seal_key,
437 ntlmssp_state->session_key, recv_seal_const);
438 dump_data_pw("NTLMSSP recv seal key:\n",
439 ntlmssp_state->recv_sign_key,
440 sizeof(ntlmssp_state->recv_seal_key));
441 dump_data_pw("NTLMSSP receive seal hash:\n",
442 ntlmssp_state->recv_sign_hash,
443 sizeof(ntlmssp_state->recv_sign_hash));
446 if (!ntlmssp_state->session_key.data) {
447 /* can't sign or check signatures yet */
448 DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY\n"));
449 return NT_STATUS_UNSUCCESSFUL;
452 DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n"));
454 calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), ntlmssp_state->session_key.length);
455 dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash,
456 sizeof(ntlmssp_state->ntlmssp_hash));
459 ntlmssp_state->ntlmssp_seq_num = 0;