diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/ntlmssp.h | 17 | ||||
-rw-r--r-- | source3/libsmb/ntlmssp_sign.c | 97 |
2 files changed, 63 insertions, 51 deletions
diff --git a/source3/include/ntlmssp.h b/source3/include/ntlmssp.h index d44df162d8..8774a0b1a9 100644 --- a/source3/include/ntlmssp.h +++ b/source3/include/ntlmssp.h @@ -42,6 +42,8 @@ enum ntlmssp_message_type #define NTLMSSP_FEATURE_SEAL 0x00000004 #define NTLMSSP_FEATURE_CCACHE 0x00000008 +union ntlmssp_crypt_state; + struct ntlmssp_state { enum ntlmssp_role role; @@ -128,18 +130,5 @@ struct ntlmssp_state */ NTSTATUS (*check_password)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key); - /* ntlmv2 */ - - unsigned char send_sign_key[16]; - unsigned char recv_sign_key[16]; - - struct arcfour_state send_seal_arc4_state; - struct arcfour_state recv_seal_arc4_state; - - uint32_t ntlm2_send_seq_num; - uint32_t ntlm2_recv_seq_num; - - /* ntlmv1 */ - struct arcfour_state ntlmv1_arc4_state; - uint32_t ntlmv1_seq_num; + union ntlmssp_crypt_state *crypt; }; diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index e14ab1e22a..331bf1127a 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -59,6 +59,23 @@ enum ntlmssp_direction { NTLMSSP_RECEIVE }; +struct ntlmssp_crypt_direction { + uint32_t seq_num; + uint8_t sign_key[16]; + struct arcfour_state seal_state; +}; + +union ntlmssp_crypt_state { + /* NTLM */ + struct ntlmssp_crypt_direction ntlm; + + /* NTLM2 */ + struct { + struct ntlmssp_crypt_direction sending; + struct ntlmssp_crypt_direction receiving; + } ntlm2; +}; + static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_state, const uint8_t *data, size_t length, const uint8_t *whole_pdu, size_t pdu_length, @@ -78,24 +95,24 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat switch (direction) { case NTLMSSP_SEND: DEBUG(100,("ntlmssp_make_packet_signature: SEND seq = %u, len = %u, pdu_len = %u\n", - ntlmssp_state->ntlm2_send_seq_num, + ntlmssp_state->crypt->ntlm2.sending.seq_num, (unsigned int)length, (unsigned int)pdu_length)); - SIVAL(seq_num, 0, ntlmssp_state->ntlm2_send_seq_num); - ntlmssp_state->ntlm2_send_seq_num++; - hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, 16, &ctx); + SIVAL(seq_num, 0, ntlmssp_state->crypt->ntlm2.sending.seq_num); + ntlmssp_state->crypt->ntlm2.sending.seq_num++; + hmac_md5_init_limK_to_64(ntlmssp_state->crypt->ntlm2.sending.sign_key, 16, &ctx); break; case NTLMSSP_RECEIVE: DEBUG(100,("ntlmssp_make_packet_signature: RECV seq = %u, len = %u, pdu_len = %u\n", - ntlmssp_state->ntlm2_recv_seq_num, + ntlmssp_state->crypt->ntlm2.receiving.seq_num, (unsigned int)length, (unsigned int)pdu_length)); - SIVAL(seq_num, 0, ntlmssp_state->ntlm2_recv_seq_num); - ntlmssp_state->ntlm2_recv_seq_num++; - hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key, 16, &ctx); + SIVAL(seq_num, 0, ntlmssp_state->crypt->ntlm2.receiving.seq_num); + ntlmssp_state->crypt->ntlm2.receiving.seq_num++; + hmac_md5_init_limK_to_64(ntlmssp_state->crypt->ntlm2.receiving.sign_key, 16, &ctx); break; } @@ -108,11 +125,11 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat if (encrypt_sig && (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { switch (direction) { case NTLMSSP_SEND: - arcfour_crypt_sbox(&ntlmssp_state->send_seal_arc4_state, + arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm2.sending.seal_state, digest, 8); break; case NTLMSSP_RECEIVE: - arcfour_crypt_sbox(&ntlmssp_state->recv_seal_arc4_state, + arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm2.receiving.seal_state, digest, 8); break; } @@ -133,16 +150,16 @@ static NTSTATUS ntlmssp_make_packet_signature(struct ntlmssp_state *ntlmssp_stat ok = msrpc_gen(ntlmssp_state, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, - ntlmssp_state->ntlmv1_seq_num); + ntlmssp_state->crypt->ntlm.seq_num); if (!ok) { return NT_STATUS_NO_MEMORY; } - ntlmssp_state->ntlmv1_seq_num++; + ntlmssp_state->crypt->ntlm.seq_num++; dump_arc4_state("ntlmssp hash: \n", - &ntlmssp_state->ntlmv1_arc4_state); - arcfour_crypt_sbox(&ntlmssp_state->ntlmv1_arc4_state, + &ntlmssp_state->crypt->ntlm.seal_state); + arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm.seal_state, sig->data+4, sig->length-4); } return NT_STATUS_OK; @@ -284,10 +301,10 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, return nt_status; } - arcfour_crypt_sbox(&ntlmssp_state->send_seal_arc4_state, + arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm2.sending.seal_state, data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { - arcfour_crypt_sbox(&ntlmssp_state->send_seal_arc4_state, + arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm2.sending.seal_state, sig->data+4, 8); } } else { @@ -299,7 +316,7 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, ok = msrpc_gen(ntlmssp_state, sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, - ntlmssp_state->ntlmv1_seq_num); + ntlmssp_state->crypt->ntlm.seq_num); if (!ok) { return NT_STATUS_NO_MEMORY; } @@ -313,17 +330,17 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state, */ dump_arc4_state("ntlmv1 arc4 state:\n", - &ntlmssp_state->ntlmv1_arc4_state); - arcfour_crypt_sbox(&ntlmssp_state->ntlmv1_arc4_state, + &ntlmssp_state->crypt->ntlm.seal_state); + arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm.seal_state, data, length); dump_arc4_state("ntlmv1 arc4 state:\n", - &ntlmssp_state->ntlmv1_arc4_state); + &ntlmssp_state->crypt->ntlm.seal_state); - arcfour_crypt_sbox(&ntlmssp_state->ntlmv1_arc4_state, + arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm.seal_state, sig->data+4, sig->length-4); - ntlmssp_state->ntlmv1_seq_num++; + ntlmssp_state->crypt->ntlm.seq_num++; } dump_data_pw("ntlmssp signature\n", sig->data, sig->length); dump_data_pw("ntlmssp sealed data\n", data, length); @@ -351,11 +368,11 @@ NTSTATUS ntlmssp_unseal_packet(struct ntlmssp_state *ntlmssp_state, if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { /* First unseal the data. */ - arcfour_crypt_sbox(&ntlmssp_state->recv_seal_arc4_state, + arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm2.receiving.seal_state, data, length); dump_data_pw("ntlmv2 clear data\n", data, length); } else { - arcfour_crypt_sbox(&ntlmssp_state->ntlmv1_arc4_state, + arcfour_crypt_sbox(&ntlmssp_state->crypt->ntlm.seal_state, data, length); dump_data_pw("ntlmv1 clear data\n", data, length); } @@ -375,6 +392,12 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) return NT_STATUS_NO_USER_SESSION_KEY; } + ntlmssp_state->crypt = talloc_zero(ntlmssp_state, + union ntlmssp_crypt_state); + if (ntlmssp_state->crypt == NULL) { + return NT_STATUS_NO_MEMORY; + } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { DATA_BLOB weak_session_key = ntlmssp_state->session_key; const char *send_sign_const; @@ -429,44 +452,44 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) weak_session_key.length); /* SEND: sign key */ - calc_ntlmv2_key(ntlmssp_state->send_sign_key, + calc_ntlmv2_key(ntlmssp_state->crypt->ntlm2.sending.sign_key, ntlmssp_state->session_key, send_sign_const); dump_data_pw("NTLMSSP send sign key:\n", - ntlmssp_state->send_sign_key, 16); + ntlmssp_state->crypt->ntlm2.sending.sign_key, 16); /* SEND: seal ARCFOUR pad */ calc_ntlmv2_key(send_seal_key, weak_session_key, send_seal_const); dump_data_pw("NTLMSSP send seal key:\n", send_seal_key, 16); - arcfour_init(&ntlmssp_state->send_seal_arc4_state, + arcfour_init(&ntlmssp_state->crypt->ntlm2.sending.seal_state, &send_seal_blob); dump_arc4_state("NTLMSSP send seal arc4 state:\n", - &ntlmssp_state->send_seal_arc4_state); + &ntlmssp_state->crypt->ntlm2.sending.seal_state); /* SEND: seq num */ - ntlmssp_state->ntlm2_send_seq_num = 0; + ntlmssp_state->crypt->ntlm2.sending.seq_num = 0; /* RECV: sign key */ - calc_ntlmv2_key(ntlmssp_state->recv_sign_key, + calc_ntlmv2_key(ntlmssp_state->crypt->ntlm2.receiving.sign_key, ntlmssp_state->session_key, recv_sign_const); dump_data_pw("NTLMSSP recv sign key:\n", - ntlmssp_state->recv_sign_key, 16); + ntlmssp_state->crypt->ntlm2.receiving.sign_key, 16); /* RECV: seal ARCFOUR pad */ calc_ntlmv2_key(recv_seal_key, weak_session_key, recv_seal_const); dump_data_pw("NTLMSSP recv seal key:\n", recv_seal_key, 16); - arcfour_init(&ntlmssp_state->recv_seal_arc4_state, + arcfour_init(&ntlmssp_state->crypt->ntlm2.receiving.seal_state, &recv_seal_blob); dump_arc4_state("NTLMSSP recv seal arc4 state:\n", - &ntlmssp_state->recv_seal_arc4_state); + &ntlmssp_state->crypt->ntlm2.receiving.seal_state); /* RECV: seq num */ - ntlmssp_state->ntlm2_recv_seq_num = 0; + ntlmssp_state->crypt->ntlm2.receiving.seq_num = 0; } else { uint8_t weak_session_key[8]; DATA_BLOB seal_session_key = ntlmssp_state->session_key; @@ -510,13 +533,13 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) } } - arcfour_init(&ntlmssp_state->ntlmv1_arc4_state, + arcfour_init(&ntlmssp_state->crypt->ntlm.seal_state, &seal_session_key); dump_arc4_state("NTLMv1 arc4 state:\n", - &ntlmssp_state->ntlmv1_arc4_state); + &ntlmssp_state->crypt->ntlm.seal_state); - ntlmssp_state->ntlmv1_seq_num = 0; + ntlmssp_state->crypt->ntlm.seq_num = 0; } return NT_STATUS_OK; |