summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/ntlmssp.h17
-rw-r--r--source3/libsmb/ntlmssp_sign.c97
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;