root/source4/auth/ntlmssp/ntlmssp_sign.c

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

DEFINITIONS

This source file includes following definitions.
  1. calc_ntlmv2_key
  2. ntlmssp_make_packet_signature
  3. gensec_ntlmssp_sign_packet
  4. gensec_ntlmssp_check_packet
  5. gensec_ntlmssp_seal_packet
  6. gensec_ntlmssp_unseal_packet
  7. ntlmssp_sign_init
  8. gensec_ntlmssp_sig_size
  9. gensec_ntlmssp_wrap
  10. gensec_ntlmssp_unwrap

   1 /* 
   2  *  Unix SMB/CIFS implementation.
   3  *  Version 3.0
   4  *  NTLMSSP Signing routines
   5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2001
   6  *  Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2005
   7  *  
   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 3 of the License, or
  11  *  (at your option) any later version.
  12  *  
  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.
  17  *  
  18  *  You should have received a copy of the GNU General Public License
  19  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  20  */
  21 
  22 #include "includes.h"
  23 #include "auth/auth.h"
  24 #include "auth/ntlmssp/ntlmssp.h"
  25 #include "auth/ntlmssp/msrpc_parse.h"
  26 #include "../lib/crypto/crypto.h"
  27 #include "auth/credentials/credentials.h"
  28 #include "auth/gensec/gensec.h"
  29 
  30 #define CLI_SIGN "session key to client-to-server signing key magic constant"
  31 #define CLI_SEAL "session key to client-to-server sealing key magic constant"
  32 #define SRV_SIGN "session key to server-to-client signing key magic constant"
  33 #define SRV_SEAL "session key to server-to-client sealing key magic constant"
  34 
  35 /**
  36  * Some notes on the NTLM2 code:
  37  *
  38  * NTLM2 is a AEAD system.  This means that the data encrypted is not
  39  * all the data that is signed.  In DCE-RPC case, the headers of the
  40  * DCE-RPC packets are also signed.  This prevents some of the
  41  * fun-and-games one might have by changing them.
  42  *
  43  */
  44 
  45 static void calc_ntlmv2_key(TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
  46                             DATA_BLOB *subkey,
  47                             DATA_BLOB session_key, 
  48                             const char *constant)
  49 {
  50         struct MD5Context ctx3;
  51         *subkey = data_blob_talloc(mem_ctx, NULL, 16);
  52         MD5Init(&ctx3);
  53         MD5Update(&ctx3, session_key.data, session_key.length);
  54         MD5Update(&ctx3, (const uint8_t *)constant, strlen(constant)+1);
  55         MD5Final(subkey->data, &ctx3);
  56 }
  57 
  58 enum ntlmssp_direction {
  59         NTLMSSP_SEND,
  60         NTLMSSP_RECEIVE
  61 };
  62 
  63 static NTSTATUS ntlmssp_make_packet_signature(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
  64                                               TALLOC_CTX *sig_mem_ctx, 
  65                                               const uint8_t *data, size_t length, 
  66                                               const uint8_t *whole_pdu, size_t pdu_length, 
  67                                               enum ntlmssp_direction direction,
  68                                               DATA_BLOB *sig, bool encrypt_sig)
  69 {
  70         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
  71 
  72                 HMACMD5Context ctx;
  73                 uint8_t digest[16];
  74                 uint8_t seq_num[4];
  75 
  76                 *sig = data_blob_talloc(sig_mem_ctx, NULL, NTLMSSP_SIG_SIZE);
  77                 if (!sig->data) {
  78                         return NT_STATUS_NO_MEMORY;
  79                 }
  80                         
  81                 switch (direction) {
  82                 case NTLMSSP_SEND:
  83                         SIVAL(seq_num, 0, gensec_ntlmssp_state->crypt.ntlm2.send_seq_num);
  84                         gensec_ntlmssp_state->crypt.ntlm2.send_seq_num++;
  85                         hmac_md5_init_limK_to_64(gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.data, 
  86                                                  gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.length, &ctx);
  87                         break;
  88                 case NTLMSSP_RECEIVE:
  89                         SIVAL(seq_num, 0, gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num);
  90                         gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num++;
  91                         hmac_md5_init_limK_to_64(gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data, 
  92                                                  gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.length, &ctx);
  93                         break;
  94                 }
  95                 hmac_md5_update(seq_num, sizeof(seq_num), &ctx);
  96                 hmac_md5_update(whole_pdu, pdu_length, &ctx);
  97                 hmac_md5_final(digest, &ctx);
  98 
  99                 if (encrypt_sig && gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
 100                         switch (direction) {
 101                         case NTLMSSP_SEND:
 102                                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, digest, 8);
 103                                 break;
 104                         case NTLMSSP_RECEIVE:
 105                                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state, digest, 8);
 106                                 break;
 107                         }
 108                 }
 109 
 110                 SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION);
 111                 memcpy(sig->data + 4, digest, 8);
 112                 memcpy(sig->data + 12, seq_num, 4);
 113 
 114                 DEBUG(10, ("NTLM2: created signature over %llu bytes of input:\n", (unsigned long long)pdu_length));
 115                 dump_data(11, sig->data, sig->length);
 116                         
 117         } else {
 118                 uint32_t crc;
 119                 crc = crc32_calc_buffer(data, length);
 120                 if (!msrpc_gen(sig_mem_ctx, 
 121                                sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, gensec_ntlmssp_state->crypt.ntlm.seq_num)) {
 122                         return NT_STATUS_NO_MEMORY;
 123                 }
 124                 gensec_ntlmssp_state->crypt.ntlm.seq_num++;
 125 
 126                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, sig->data+4, sig->length-4);
 127 
 128                 DEBUG(10, ("NTLM1: created signature over %llu bytes of input:\n", (unsigned long long)length));
 129                 dump_data(11, sig->data, sig->length);
 130         }
 131         return NT_STATUS_OK;
 132 }
 133 
 134 /* TODO: make this non-public */
 135 NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security, 
     /* [<][>][^][v][top][bottom][index][help] */
 136                                     TALLOC_CTX *sig_mem_ctx, 
 137                                     const uint8_t *data, size_t length, 
 138                                     const uint8_t *whole_pdu, size_t pdu_length, 
 139                                     DATA_BLOB *sig)
 140 {
 141         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
 142 
 143         return ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx, 
 144                                              data, length, 
 145                                              whole_pdu, pdu_length, 
 146                                              NTLMSSP_SEND, sig, true);
 147 }
 148 
 149 /**
 150  * Check the signature of an incoming packet 
 151  *
 152  */
 153 
 154 NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security, 
     /* [<][>][^][v][top][bottom][index][help] */
 155                                      TALLOC_CTX *sig_mem_ctx, 
 156                                      const uint8_t *data, size_t length, 
 157                                      const uint8_t *whole_pdu, size_t pdu_length, 
 158                                      const DATA_BLOB *sig)
 159 {
 160         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
 161 
 162         DATA_BLOB local_sig;
 163         NTSTATUS nt_status;
 164 
 165         if (!gensec_ntlmssp_state->session_key.length) {
 166                 DEBUG(3, ("NO session key, cannot check packet signature\n"));
 167                 return NT_STATUS_NO_USER_SESSION_KEY;
 168         }
 169 
 170         nt_status = ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx, 
 171                                                   data, length, 
 172                                                   whole_pdu, pdu_length, 
 173                                                   NTLMSSP_RECEIVE, &local_sig, true);
 174         
 175         if (!NT_STATUS_IS_OK(nt_status)) {
 176                 DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status)));
 177                 return nt_status;
 178         }
 179 
 180         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
 181                 if (local_sig.length != sig->length ||
 182                     memcmp(local_sig.data, 
 183                            sig->data, sig->length) != 0) {
 184                         DEBUG(5, ("BAD SIG NTLM2: wanted signature over %llu bytes of input:\n", (unsigned long long)pdu_length));
 185                         dump_data(5, local_sig.data, local_sig.length);
 186                         
 187                         DEBUG(5, ("BAD SIG: got signature over %llu bytes of input:\n", (unsigned long long)pdu_length));
 188                         dump_data(5, sig->data, sig->length);
 189                         
 190                         DEBUG(1, ("NTLMSSP NTLM2 packet check failed due to invalid signature on %llu bytes of input!\n", (unsigned long long)pdu_length));
 191                         return NT_STATUS_ACCESS_DENIED;
 192                 }
 193         } else {
 194                 if (local_sig.length != sig->length ||
 195                     memcmp(local_sig.data + 8, 
 196                            sig->data + 8, sig->length - 8) != 0) {
 197                         DEBUG(5, ("BAD SIG NTLM1: wanted signature of %llu bytes of input:\n", (unsigned long long)length));
 198                         dump_data(5, local_sig.data, local_sig.length);
 199                         
 200                         DEBUG(5, ("BAD SIG: got signature of %llu bytes of input:\n", (unsigned long long)length));
 201                         dump_data(5, sig->data, sig->length);
 202                         
 203                         DEBUG(1, ("NTLMSSP NTLM1 packet check failed due to invalid signature on %llu bytes of input:\n", (unsigned long long)length));
 204                         return NT_STATUS_ACCESS_DENIED;
 205                 }
 206         }
 207         dump_data_pw("checked ntlmssp signature\n", sig->data, sig->length);
 208 
 209         return NT_STATUS_OK;
 210 }
 211 
 212 
 213 /**
 214  * Seal data with the NTLMSSP algorithm
 215  *
 216  */
 217 
 218 NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security, 
     /* [<][>][^][v][top][bottom][index][help] */
 219                                     TALLOC_CTX *sig_mem_ctx, 
 220                                     uint8_t *data, size_t length, 
 221                                     const uint8_t *whole_pdu, size_t pdu_length, 
 222                                     DATA_BLOB *sig)
 223 {
 224         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
 225         NTSTATUS nt_status;
 226         if (!gensec_ntlmssp_state->session_key.length) {
 227                 DEBUG(3, ("NO session key, cannot seal packet\n"));
 228                 return NT_STATUS_NO_USER_SESSION_KEY;
 229         }
 230 
 231         DEBUG(10,("ntlmssp_seal_data: seal\n"));
 232         dump_data_pw("ntlmssp clear data\n", data, length);
 233         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
 234                 /* The order of these two operations matters - we must first seal the packet,
 235                    then seal the sequence number - this is becouse the send_seal_hash is not
 236                    constant, but is is rather updated with each iteration */
 237                 nt_status = ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx, 
 238                                                           data, length, 
 239                                                           whole_pdu, pdu_length, 
 240                                                           NTLMSSP_SEND, sig, false);
 241                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, data, length);
 242                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
 243                         arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, sig->data+4, 8);
 244                 }
 245         } else {
 246                 uint32_t crc;
 247                 crc = crc32_calc_buffer(data, length);
 248                 if (!msrpc_gen(sig_mem_ctx, 
 249                                sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, gensec_ntlmssp_state->crypt.ntlm.seq_num)) {
 250                         return NT_STATUS_NO_MEMORY;
 251                 }
 252 
 253                 /* The order of these two operations matters - we must
 254                    first seal the packet, then seal the sequence
 255                    number - this is becouse the ntlmssp_hash is not
 256                    constant, but is is rather updated with each
 257                    iteration */
 258 
 259                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, data, length);
 260                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, sig->data+4, sig->length-4);
 261                 /* increment counter on send */
 262                 gensec_ntlmssp_state->crypt.ntlm.seq_num++;
 263                 nt_status = NT_STATUS_OK;
 264         }
 265         dump_data_pw("ntlmssp signature\n", sig->data, sig->length);
 266         dump_data_pw("ntlmssp sealed data\n", data, length);
 267 
 268 
 269         return nt_status;
 270 }
 271 
 272 /**
 273  * Unseal data with the NTLMSSP algorithm
 274  *
 275  */
 276 
 277 /*
 278   wrappers for the ntlmssp_*() functions
 279 */
 280 NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, 
     /* [<][>][^][v][top][bottom][index][help] */
 281                                       TALLOC_CTX *sig_mem_ctx, 
 282                                       uint8_t *data, size_t length, 
 283                                       const uint8_t *whole_pdu, size_t pdu_length, 
 284                                       const DATA_BLOB *sig)
 285 {
 286         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
 287         if (!gensec_ntlmssp_state->session_key.length) {
 288                 DEBUG(3, ("NO session key, cannot unseal packet\n"));
 289                 return NT_STATUS_NO_USER_SESSION_KEY;
 290         }
 291 
 292         dump_data_pw("ntlmssp sealed data\n", data, length);
 293         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
 294                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state, data, length);
 295         } else {
 296                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, data, length);
 297         }
 298         dump_data_pw("ntlmssp clear data\n", data, length);
 299         return gensec_ntlmssp_check_packet(gensec_security, sig_mem_ctx, data, length, whole_pdu, pdu_length, sig);
 300 }
 301 
 302 /**
 303    Initialise the state for NTLMSSP signing.
 304 */
 305 /* TODO: make this non-public */
 306 NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
     /* [<][>][^][v][top][bottom][index][help] */
 307 {
 308         TALLOC_CTX *mem_ctx = talloc_new(gensec_ntlmssp_state);
 309 
 310         if (!mem_ctx) {
 311                 return NT_STATUS_NO_MEMORY;
 312         }
 313 
 314         DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n"));
 315         debug_ntlmssp_flags(gensec_ntlmssp_state->neg_flags);
 316 
 317         if (gensec_ntlmssp_state->session_key.length < 8) {
 318                 talloc_free(mem_ctx);
 319                 DEBUG(3, ("NO session key, cannot intialise signing\n"));
 320                 return NT_STATUS_NO_USER_SESSION_KEY;
 321         }
 322 
 323         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
 324         {
 325                 DATA_BLOB weak_session_key = gensec_ntlmssp_state->session_key;
 326                 const char *send_sign_const;
 327                 const char *send_seal_const;
 328                 const char *recv_sign_const;
 329                 const char *recv_seal_const;
 330 
 331                 DATA_BLOB send_seal_key;
 332                 DATA_BLOB recv_seal_key;
 333 
 334                 switch (gensec_ntlmssp_state->role) {
 335                 case NTLMSSP_CLIENT:
 336                         send_sign_const = CLI_SIGN;
 337                         send_seal_const = CLI_SEAL;
 338                         recv_sign_const = SRV_SIGN;
 339                         recv_seal_const = SRV_SEAL;
 340                         break;
 341                 case NTLMSSP_SERVER:
 342                         send_sign_const = SRV_SIGN;
 343                         send_seal_const = SRV_SEAL;
 344                         recv_sign_const = CLI_SIGN;
 345                         recv_seal_const = CLI_SEAL;
 346                         break;
 347                 default:
 348                         talloc_free(mem_ctx);
 349                         return NT_STATUS_INTERNAL_ERROR;
 350                 }
 351                 
 352                 gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state);
 353                 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state);
 354                 gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state);
 355                 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state);
 356 
 357                 /**
 358                    Weaken NTLMSSP keys to cope with down-level
 359                    clients, servers and export restrictions.
 360                    
 361                    We probably should have some parameters to control
 362                    this, once we get NTLM2 working.
 363                 */
 364 
 365                 /* Key weakening was not performed on the master key
 366                  * for NTLM2 (in ntlmssp_weaken_keys()), but must be
 367                  * done on the encryption subkeys only.  That is why
 368                  * we don't have this code for the ntlmv1 case.
 369                  */
 370 
 371                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
 372                         
 373                 } else if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
 374                         weak_session_key.length = 7;
 375                 } else { /* forty bits */
 376                         weak_session_key.length = 5;
 377                 }
 378                 dump_data_pw("NTLMSSP weakend master key:\n",
 379                              weak_session_key.data, 
 380                              weak_session_key.length);
 381 
 382                 /* SEND: sign key */
 383                 calc_ntlmv2_key(gensec_ntlmssp_state, 
 384                                 &gensec_ntlmssp_state->crypt.ntlm2.send_sign_key, 
 385                                 gensec_ntlmssp_state->session_key, send_sign_const);
 386                 dump_data_pw("NTLMSSP send sign key:\n",
 387                              gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.data, 
 388                              gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.length);
 389                 
 390                 /* SEND: seal ARCFOUR pad */
 391                 calc_ntlmv2_key(mem_ctx, 
 392                                 &send_seal_key, 
 393                                 weak_session_key, send_seal_const);
 394                 dump_data_pw("NTLMSSP send seal key:\n",
 395                              send_seal_key.data, 
 396                              send_seal_key.length);
 397                 arcfour_init(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, 
 398                              &send_seal_key);
 399                 dump_data_pw("NTLMSSP send sesl hash:\n", 
 400                              gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state->sbox, 
 401                              sizeof(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state->sbox));
 402 
 403                 /* RECV: sign key */
 404                 calc_ntlmv2_key(gensec_ntlmssp_state, 
 405                                 &gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key, 
 406                                 gensec_ntlmssp_state->session_key, recv_sign_const);
 407                 dump_data_pw("NTLMSSP recv sign key:\n",
 408                              gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data, 
 409                              gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.length);
 410 
 411                 /* RECV: seal ARCFOUR pad */
 412                 calc_ntlmv2_key(mem_ctx, 
 413                                 &recv_seal_key, 
 414                                 weak_session_key, recv_seal_const);
 415                 dump_data_pw("NTLMSSP recv seal key:\n",
 416                              recv_seal_key.data, 
 417                              recv_seal_key.length);
 418                 arcfour_init(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state, 
 419                              &recv_seal_key);
 420                 dump_data_pw("NTLMSSP receive seal hash:\n", 
 421                              gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state->sbox, 
 422                              sizeof(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state->sbox));
 423 
 424                 gensec_ntlmssp_state->crypt.ntlm2.send_seq_num = 0;
 425                 gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num = 0;
 426 
 427         } else {
 428                 DATA_BLOB weak_session_key = ntlmssp_weakend_key(gensec_ntlmssp_state, mem_ctx);
 429                 DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n"));
 430 
 431                 gensec_ntlmssp_state->crypt.ntlm.arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state);
 432                 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm.arcfour_state);
 433 
 434                 arcfour_init(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, 
 435                              &weak_session_key);
 436                 dump_data_pw("NTLMSSP hash:\n", gensec_ntlmssp_state->crypt.ntlm.arcfour_state->sbox,
 437                              sizeof(gensec_ntlmssp_state->crypt.ntlm.arcfour_state->sbox));
 438 
 439                 gensec_ntlmssp_state->crypt.ntlm.seq_num = 0;
 440         }
 441 
 442         talloc_free(mem_ctx);
 443         return NT_STATUS_OK;
 444 }
 445 
 446 size_t gensec_ntlmssp_sig_size(struct gensec_security *gensec_security, size_t data_size) 
     /* [<][>][^][v][top][bottom][index][help] */
 447 {
 448         return NTLMSSP_SIG_SIZE;
 449 }
 450 
 451 NTSTATUS gensec_ntlmssp_wrap(struct gensec_security *gensec_security, 
     /* [<][>][^][v][top][bottom][index][help] */
 452                              TALLOC_CTX *sig_mem_ctx, 
 453                              const DATA_BLOB *in, 
 454                              DATA_BLOB *out)
 455 {
 456         DATA_BLOB sig;
 457         NTSTATUS nt_status;
 458 
 459         if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
 460 
 461                 *out = data_blob_talloc(sig_mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE);
 462                 if (!out->data) {
 463                         return NT_STATUS_NO_MEMORY;
 464                 }
 465                 memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length);
 466                 
 467                 nt_status = gensec_ntlmssp_seal_packet(gensec_security, sig_mem_ctx, 
 468                                                        out->data + NTLMSSP_SIG_SIZE, 
 469                                                        out->length - NTLMSSP_SIG_SIZE, 
 470                                                        out->data + NTLMSSP_SIG_SIZE, 
 471                                                        out->length - NTLMSSP_SIG_SIZE, 
 472                                                        &sig);
 473                 
 474                 if (NT_STATUS_IS_OK(nt_status)) {
 475                         memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE);
 476                 }
 477                 return nt_status;
 478 
 479         } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
 480 
 481                 *out = data_blob_talloc(sig_mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE);
 482                 if (!out->data) {
 483                         return NT_STATUS_NO_MEMORY;
 484                 }
 485                 memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length);
 486 
 487                 nt_status = gensec_ntlmssp_sign_packet(gensec_security, sig_mem_ctx, 
 488                                                        out->data + NTLMSSP_SIG_SIZE, 
 489                                                        out->length - NTLMSSP_SIG_SIZE, 
 490                                                        out->data + NTLMSSP_SIG_SIZE, 
 491                                                        out->length - NTLMSSP_SIG_SIZE, 
 492                                                        &sig);
 493 
 494                 if (NT_STATUS_IS_OK(nt_status)) {
 495                         memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE);
 496                 }
 497                 return nt_status;
 498 
 499         } else {
 500                 *out = *in;
 501                 return NT_STATUS_OK;
 502         }
 503 }
 504 
 505 
 506 NTSTATUS gensec_ntlmssp_unwrap(struct gensec_security *gensec_security, 
     /* [<][>][^][v][top][bottom][index][help] */
 507                                TALLOC_CTX *sig_mem_ctx, 
 508                                const DATA_BLOB *in, 
 509                                DATA_BLOB *out)
 510 {
 511         DATA_BLOB sig;
 512 
 513         if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
 514                 if (in->length < NTLMSSP_SIG_SIZE) {
 515                         return NT_STATUS_INVALID_PARAMETER;
 516                 }
 517                 sig.data = in->data;
 518                 sig.length = NTLMSSP_SIG_SIZE;
 519 
 520                 *out = data_blob_talloc(sig_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE);
 521                 
 522                 return gensec_ntlmssp_unseal_packet(gensec_security, sig_mem_ctx, 
 523                                                     out->data, out->length, 
 524                                                     out->data, out->length, 
 525                                                     &sig);
 526                                                   
 527         } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
 528                 if (in->length < NTLMSSP_SIG_SIZE) {
 529                         return NT_STATUS_INVALID_PARAMETER;
 530                 }
 531                 sig.data = in->data;
 532                 sig.length = NTLMSSP_SIG_SIZE;
 533 
 534                 *out = data_blob_talloc(sig_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE);
 535                 
 536                 return gensec_ntlmssp_check_packet(gensec_security, sig_mem_ctx, 
 537                                                    out->data, out->length, 
 538                                                    out->data, out->length, 
 539                                                    &sig);
 540         } else {
 541                 *out = *in;
 542                 return NT_STATUS_OK;
 543         }
 544 }
 545 

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