root/source3/libsmb/ntlmssp_sign.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dump_arc4_state
  2. calc_ntlmv2_key
  3. ntlmssp_make_packet_signature
  4. ntlmssp_sign_packet
  5. ntlmssp_check_packet
  6. ntlmssp_seal_packet
  7. ntlmssp_unseal_packet
  8. ntlmssp_sign_init

   1 /* 
   2  *  Unix SMB/CIFS implementation.
   3  *  Version 3.0
   4  *  NTLMSSP Signing routines
   5  *  Copyright (C) Andrew Bartlett 2003-2005
   6  *  
   7  *  This program is free software; you can redistribute it and/or modify
   8  *  it under the terms of the GNU General Public License as published by
   9  *  the Free Software Foundation; either version 3 of the License, or
  10  *  (at your option) any later version.
  11  *  
  12  *  This program is distributed in the hope that it will be useful,
  13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  *  GNU General Public License for more details.
  16  *  
  17  *  You should have received a copy of the GNU General Public License
  18  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  19  */
  20 
  21 #include "includes.h"
  22 
  23 #define CLI_SIGN "session key to client-to-server signing key magic constant"
  24 #define CLI_SEAL "session key to client-to-server sealing key magic constant"
  25 #define SRV_SIGN "session key to server-to-client signing key magic constant"
  26 #define SRV_SEAL "session key to server-to-client sealing key magic constant"
  27 
  28 /**
  29  * Some notes on then NTLM2 code:
  30  *
  31  * NTLM2 is a AEAD system.  This means that the data encrypted is not
  32  * all the data that is signed.  In DCE-RPC case, the headers of the
  33  * DCE-RPC packets are also signed.  This prevents some of the
  34  * fun-and-games one might have by changing them.
  35  *
  36  */
  37 
  38 static void dump_arc4_state(const char *description, 
     /* [<][>][^][v][top][bottom][index][help] */
  39                             struct arcfour_state *state)
  40 {
  41         dump_data_pw(description, state->sbox, sizeof(state->sbox));
  42 }
  43 
  44 static void calc_ntlmv2_key(unsigned char subkey[16],
     /* [<][>][^][v][top][bottom][index][help] */
  45                                 DATA_BLOB session_key,
  46                                 const char *constant)
  47 {
  48         struct MD5Context ctx3;
  49         MD5Init(&ctx3);
  50         MD5Update(&ctx3, session_key.data, session_key.length);
  51         MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)+1);
  52         MD5Final(subkey, &ctx3);
  53 }
  54 
  55 enum ntlmssp_direction {
  56         NTLMSSP_SEND,
  57         NTLMSSP_RECEIVE
  58 };
  59 
  60 static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
  61                                                 const uchar *data, size_t length, 
  62                                                 const uchar *whole_pdu, size_t pdu_length,
  63                                                 enum ntlmssp_direction direction,
  64                                                 DATA_BLOB *sig,
  65                                                 bool encrypt_sig)
  66 {
  67         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
  68                 HMACMD5Context ctx;
  69                 uchar seq_num[4];
  70                 uchar digest[16];
  71 
  72                 *sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
  73                 if (!sig->data) {
  74                         return NT_STATUS_NO_MEMORY;
  75                 }
  76 
  77                 switch (direction) {
  78                         case NTLMSSP_SEND:
  79                                 DEBUG(100,("ntlmssp_make_packet_signature: SEND seq = %u, len = %u, pdu_len = %u\n",
  80                                         ntlmssp_state->ntlm2_send_seq_num,
  81                                         (unsigned int)length,
  82                                         (unsigned int)pdu_length));
  83 
  84                                 SIVAL(seq_num, 0, ntlmssp_state->ntlm2_send_seq_num);
  85                                 ntlmssp_state->ntlm2_send_seq_num++;
  86                                 hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, 16, &ctx);
  87                                 break;
  88                         case NTLMSSP_RECEIVE:
  89 
  90                                 DEBUG(100,("ntlmssp_make_packet_signature: RECV seq = %u, len = %u, pdu_len = %u\n",
  91                                         ntlmssp_state->ntlm2_recv_seq_num,
  92                                         (unsigned int)length,
  93                                         (unsigned int)pdu_length));
  94 
  95                                 SIVAL(seq_num, 0, ntlmssp_state->ntlm2_recv_seq_num);
  96                                 ntlmssp_state->ntlm2_recv_seq_num++;
  97                                 hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key, 16, &ctx);
  98                                 break;
  99                 }
 100 
 101                 dump_data_pw("pdu data ", whole_pdu, pdu_length);
 102 
 103                 hmac_md5_update(seq_num, 4, &ctx);
 104                 hmac_md5_update(whole_pdu, pdu_length, &ctx);
 105                 hmac_md5_final(digest, &ctx);
 106 
 107                 if (encrypt_sig && (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
 108                         switch (direction) {
 109                         case NTLMSSP_SEND:
 110                                 arcfour_crypt_sbox(&ntlmssp_state->send_seal_arc4_state, digest, 8);
 111                                 break;
 112                         case NTLMSSP_RECEIVE:
 113                                 arcfour_crypt_sbox(&ntlmssp_state->recv_seal_arc4_state, digest, 8);
 114                                 break;
 115                         }
 116                 }
 117 
 118                 SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION);
 119                 memcpy(sig->data + 4, digest, 8);
 120                 memcpy(sig->data + 12, seq_num, 4);
 121 
 122                 dump_data_pw("ntlmssp v2 sig ", sig->data, sig->length);
 123 
 124         } else {
 125                 uint32 crc;
 126                 crc = crc32_calc_buffer(data, length);
 127                 if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmv1_seq_num)) {
 128                         return NT_STATUS_NO_MEMORY;
 129                 }
 130                 
 131                 ntlmssp_state->ntlmv1_seq_num++;
 132 
 133                 dump_arc4_state("ntlmssp hash: \n", &ntlmssp_state->ntlmv1_arc4_state);
 134                 arcfour_crypt_sbox(&ntlmssp_state->ntlmv1_arc4_state, sig->data+4, sig->length-4);
 135         }
 136         return NT_STATUS_OK;
 137 }
 138 
 139 NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
 140                                     const uchar *data, size_t length, 
 141                                     const uchar *whole_pdu, size_t pdu_length, 
 142                                     DATA_BLOB *sig) 
 143 {
 144         NTSTATUS nt_status;
 145 
 146         if (!(ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
 147                 DEBUG(3, ("NTLMSSP Signing not negotiated - cannot sign packet!\n"));
 148                 return NT_STATUS_INVALID_PARAMETER;
 149         }
 150 
 151         if (!ntlmssp_state->session_key.length) {
 152                 DEBUG(3, ("NO session key, cannot check sign packet\n"));
 153                 return NT_STATUS_NO_USER_SESSION_KEY;
 154         }
 155 
 156         nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
 157                                                 data, length,
 158                                                 whole_pdu, pdu_length,
 159                                                 NTLMSSP_SEND, sig, True);
 160 
 161         return nt_status;
 162 }
 163 
 164 /**
 165  * Check the signature of an incoming packet 
 166  * @note caller *must* check that the signature is the size it expects 
 167  *
 168  */
 169 
 170 NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
 171                                 const uchar *data, size_t length, 
 172                                 const uchar *whole_pdu, size_t pdu_length, 
 173                                 const DATA_BLOB *sig) 
 174 {
 175         DATA_BLOB local_sig;
 176         NTSTATUS nt_status;
 177 
 178         if (!ntlmssp_state->session_key.length) {
 179                 DEBUG(3, ("NO session key, cannot check packet signature\n"));
 180                 return NT_STATUS_NO_USER_SESSION_KEY;
 181         }
 182 
 183         if (sig->length < 8) {
 184                 DEBUG(0, ("NTLMSSP packet check failed due to short signature (%lu bytes)!\n", 
 185                           (unsigned long)sig->length));
 186         }
 187 
 188         nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
 189                                                 data, length,
 190                                                 whole_pdu, pdu_length,
 191                                                 NTLMSSP_RECEIVE, &local_sig, True);
 192         
 193         if (!NT_STATUS_IS_OK(nt_status)) {
 194                 DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status)));
 195                 data_blob_free(&local_sig);
 196                 return nt_status;
 197         }
 198         
 199         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
 200                 if (local_sig.length != sig->length ||
 201                                 memcmp(local_sig.data, sig->data, sig->length) != 0) {
 202                         DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n"));
 203                         dump_data(5, local_sig.data, local_sig.length);
 204 
 205                         DEBUG(5, ("BAD SIG: got signature of\n"));
 206                         dump_data(5, sig->data, sig->length);
 207 
 208                         DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n"));
 209                         data_blob_free(&local_sig);
 210                         return NT_STATUS_ACCESS_DENIED;
 211                 }
 212         } else {
 213                 if (local_sig.length != sig->length ||
 214                                 memcmp(local_sig.data + 8, sig->data + 8, sig->length - 8) != 0) {
 215                         DEBUG(5, ("BAD SIG NTLM1: wanted signature of\n"));
 216                         dump_data(5, local_sig.data, local_sig.length);
 217 
 218                         DEBUG(5, ("BAD SIG: got signature of\n"));
 219                         dump_data(5, sig->data, sig->length);
 220 
 221                         DEBUG(0, ("NTLMSSP NTLM1 packet check failed due to invalid signature!\n"));
 222                         data_blob_free(&local_sig);
 223                         return NT_STATUS_ACCESS_DENIED;
 224                 }
 225         }
 226         dump_data_pw("checked ntlmssp signature\n", sig->data, sig->length);
 227         DEBUG(10,("ntlmssp_check_packet: NTLMSSP signature OK !\n"));
 228 
 229         data_blob_free(&local_sig);
 230         return NT_STATUS_OK;
 231 }
 232 
 233 /**
 234  * Seal data with the NTLMSSP algorithm
 235  *
 236  */
 237 
 238 NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
 239                              uchar *data, size_t length,
 240                              uchar *whole_pdu, size_t pdu_length,
 241                              DATA_BLOB *sig)
 242 {       
 243         if (!(ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
 244                 DEBUG(3, ("NTLMSSP Sealing not negotiated - cannot seal packet!\n"));
 245                 return NT_STATUS_INVALID_PARAMETER;
 246         }
 247 
 248         if (!ntlmssp_state->session_key.length) {
 249                 DEBUG(3, ("NO session key, cannot seal packet\n"));
 250                 return NT_STATUS_NO_USER_SESSION_KEY;
 251         }
 252 
 253         DEBUG(10,("ntlmssp_seal_data: seal\n"));
 254         dump_data_pw("ntlmssp clear data\n", data, length);
 255         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
 256                 /* The order of these two operations matters - we must first seal the packet,
 257                    then seal the sequence number - this is becouse the send_seal_hash is not
 258                    constant, but is is rather updated with each iteration */
 259                 NTSTATUS nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
 260                                                         data, length,
 261                                                         whole_pdu, pdu_length,
 262                                                         NTLMSSP_SEND, sig, False);
 263                 if (!NT_STATUS_IS_OK(nt_status)) {
 264                         return nt_status;
 265                 }
 266 
 267                 arcfour_crypt_sbox(&ntlmssp_state->send_seal_arc4_state, data, length);
 268                 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
 269                         arcfour_crypt_sbox(&ntlmssp_state->send_seal_arc4_state, sig->data+4, 8);
 270                 }
 271         } else {
 272                 uint32 crc;
 273                 crc = crc32_calc_buffer(data, length);
 274                 if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmv1_seq_num)) {
 275                         return NT_STATUS_NO_MEMORY;
 276                 }
 277 
 278                 /* The order of these two operations matters - we must first seal the packet,
 279                    then seal the sequence number - this is becouse the ntlmv1_arc4_state is not
 280                    constant, but is is rather updated with each iteration */
 281                 
 282                 dump_arc4_state("ntlmv1 arc4 state:\n", 
 283                                                 &ntlmssp_state->ntlmv1_arc4_state);
 284                 arcfour_crypt_sbox(&ntlmssp_state->ntlmv1_arc4_state, data, length);
 285 
 286                 dump_arc4_state("ntlmv1 arc4 state:\n", 
 287                                                 &ntlmssp_state->ntlmv1_arc4_state);
 288 
 289                 arcfour_crypt_sbox(&ntlmssp_state->ntlmv1_arc4_state, sig->data+4, sig->length-4);
 290 
 291                 ntlmssp_state->ntlmv1_seq_num++;
 292         }
 293         dump_data_pw("ntlmssp signature\n", sig->data, sig->length);
 294         dump_data_pw("ntlmssp sealed data\n", data, length);
 295 
 296         return NT_STATUS_OK;
 297 }
 298 
 299 /**
 300  * Unseal data with the NTLMSSP algorithm
 301  *
 302  */
 303 
 304 NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
 305                                 uchar *data, size_t length,
 306                                 uchar *whole_pdu, size_t pdu_length,
 307                                 DATA_BLOB *sig)
 308 {
 309         if (!ntlmssp_state->session_key.length) {
 310                 DEBUG(3, ("NO session key, cannot unseal packet\n"));
 311                 return NT_STATUS_NO_USER_SESSION_KEY;
 312         }
 313 
 314         DEBUG(10,("ntlmssp_unseal_packet: seal\n"));
 315         dump_data_pw("ntlmssp sealed data\n", data, length);
 316 
 317         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
 318                 /* First unseal the data. */
 319                 arcfour_crypt_sbox(&ntlmssp_state->recv_seal_arc4_state, data, length);
 320                 dump_data_pw("ntlmv2 clear data\n", data, length);
 321         } else {
 322                 arcfour_crypt_sbox(&ntlmssp_state->ntlmv1_arc4_state, data, length);
 323                 dump_data_pw("ntlmv1 clear data\n", data, length);
 324         }
 325         return ntlmssp_check_packet(ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
 326 }
 327 
 328 /**
 329    Initialise the state for NTLMSSP signing.
 330 */
 331 NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state)
     /* [<][>][^][v][top][bottom][index][help] */
 332 {
 333         unsigned char p24[24];
 334         TALLOC_CTX *mem_ctx;
 335         ZERO_STRUCT(p24);
 336 
 337         mem_ctx = talloc_init("weak_keys");
 338         if (!mem_ctx) {
 339                 return NT_STATUS_NO_MEMORY;
 340         }
 341 
 342         DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n"));
 343         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
 344 
 345         if (ntlmssp_state->session_key.length < 8) {
 346                 TALLOC_FREE(mem_ctx);
 347                 DEBUG(3, ("NO session key, cannot intialise signing\n"));
 348                 return NT_STATUS_NO_USER_SESSION_KEY;
 349         }
 350 
 351         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
 352                 DATA_BLOB weak_session_key = ntlmssp_state->session_key;
 353                 const char *send_sign_const;
 354                 const char *send_seal_const;
 355                 const char *recv_sign_const;
 356                 const char *recv_seal_const;
 357                 DATA_BLOB send_seal_key_blob, recv_seal_blob;
 358 
 359                 switch (ntlmssp_state->role) {
 360                 case NTLMSSP_CLIENT:
 361                         send_sign_const = CLI_SIGN;
 362                         send_seal_const = CLI_SEAL;
 363                         recv_sign_const = SRV_SIGN;
 364                         recv_seal_const = SRV_SEAL;
 365                         break;
 366                 case NTLMSSP_SERVER:
 367                         send_sign_const = SRV_SIGN;
 368                         send_seal_const = SRV_SEAL;
 369                         recv_sign_const = CLI_SIGN;
 370                         recv_seal_const = CLI_SEAL;
 371                         break;
 372                 default:
 373                         TALLOC_FREE(mem_ctx);
 374                         return NT_STATUS_INTERNAL_ERROR;
 375                 }
 376 
 377                 /**
 378                   Weaken NTLMSSP keys to cope with down-level clients, servers and export restrictions.
 379                   We probably should have some parameters to control this, once we get NTLM2 working.
 380                 */
 381 
 382                 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
 383                         ;
 384                 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
 385                         weak_session_key.length = 7;
 386                 } else { /* forty bits */
 387                         weak_session_key.length = 5;
 388                 }
 389 
 390                 dump_data_pw("NTLMSSP weakend master key:\n",
 391                                 weak_session_key.data,
 392                                 weak_session_key.length);
 393 
 394                 /* SEND: sign key */
 395                 calc_ntlmv2_key(ntlmssp_state->send_sign_key,
 396                                 ntlmssp_state->session_key, send_sign_const);
 397                 dump_data_pw("NTLMSSP send sign key:\n",
 398                                 ntlmssp_state->send_sign_key, 16);
 399 
 400                 /* SEND: seal ARCFOUR pad */
 401                 calc_ntlmv2_key(ntlmssp_state->send_seal_key,
 402                                 weak_session_key, send_seal_const);
 403                 dump_data_pw("NTLMSSP send seal key:\n",
 404                                 ntlmssp_state->send_seal_key, 16);
 405 
 406                 send_seal_key_blob.data = ntlmssp_state->send_seal_key;
 407                 send_seal_key_blob.length = 16;
 408                 arcfour_init(&ntlmssp_state->send_seal_arc4_state, 
 409                              &send_seal_key_blob);
 410 
 411                 dump_arc4_state("NTLMSSP send seal arc4 state:\n", 
 412                              &ntlmssp_state->send_seal_arc4_state);
 413 
 414                 /* RECV: sign key */
 415                 calc_ntlmv2_key(ntlmssp_state->recv_sign_key,
 416                                 ntlmssp_state->session_key, recv_sign_const);
 417                 dump_data_pw("NTLMSSP recv send sign key:\n",
 418                                 ntlmssp_state->recv_sign_key, 16);
 419 
 420                 /* RECV: seal ARCFOUR pad */
 421                 calc_ntlmv2_key(ntlmssp_state->recv_seal_key,
 422                                 weak_session_key, recv_seal_const);
 423                 
 424                 dump_data_pw("NTLMSSP recv seal key:\n",
 425                                 ntlmssp_state->recv_seal_key, 16);
 426                                 
 427                 recv_seal_blob.data = ntlmssp_state->recv_seal_key;
 428                 recv_seal_blob.length = 16;
 429                 arcfour_init(&ntlmssp_state->recv_seal_arc4_state,
 430                                 &recv_seal_blob);
 431 
 432                 dump_arc4_state("NTLMSSP recv seal arc4 state:\n", 
 433                              &ntlmssp_state->recv_seal_arc4_state);
 434 
 435                 ntlmssp_state->ntlm2_send_seq_num = 0;
 436                 ntlmssp_state->ntlm2_recv_seq_num = 0;
 437 
 438 
 439         } else {
 440 #if 0
 441                 /* Hmmm. Shouldn't we also weaken keys for ntlmv1 ? JRA. */
 442 
 443                 DATA_BLOB weak_session_key = ntlmssp_state->session_key;
 444                 /**
 445                   Weaken NTLMSSP keys to cope with down-level clients, servers and export restrictions.
 446                   We probably should have some parameters to control this, once we get NTLM2 working.
 447                 */
 448 
 449                 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
 450                         ;
 451                 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
 452                         weak_session_key.length = 6;
 453                 } else { /* forty bits */
 454                         weak_session_key.length = 5;
 455                 }
 456                 dump_data_pw("NTLMSSP weakend master key:\n",
 457                                 weak_session_key.data,
 458                                 weak_session_key.length);
 459 #endif
 460 
 461                 DATA_BLOB weak_session_key = ntlmssp_weaken_keys(ntlmssp_state, mem_ctx);
 462 
 463                 DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n"));
 464 
 465                 arcfour_init(&ntlmssp_state->ntlmv1_arc4_state, 
 466                              &weak_session_key);
 467 
 468                 dump_arc4_state("NTLMv1 arc4 state:\n", 
 469                                 &ntlmssp_state->ntlmv1_arc4_state);
 470 
 471                 ntlmssp_state->ntlmv1_seq_num = 0;
 472         }
 473 
 474         TALLOC_FREE(mem_ctx);
 475         return NT_STATUS_OK;
 476 }

/* [<][>][^][v][top][bottom][index][help] */