summaryrefslogtreecommitdiffstats
path: root/src/ntlm_crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ntlm_crypto.c')
-rw-r--r--src/ntlm_crypto.c84
1 files changed, 73 insertions, 11 deletions
diff --git a/src/ntlm_crypto.c b/src/ntlm_crypto.c
index d999d0f..1993148 100644
--- a/src/ntlm_crypto.c
+++ b/src/ntlm_crypto.c
@@ -409,18 +409,14 @@ int ntlm_exported_session_key(struct ntlm_key *key_exchange_key,
return RAND_BUFFER(&nonce);
}
-int ntlm_encrypted_session_key(struct ntlm_key *key_exchange_key,
- struct ntlm_key *exported_session_key,
- struct ntlm_key *encrypted_random_session_key)
+int ntlm_encrypted_session_key(struct ntlm_key *key,
+ struct ntlm_key *in, struct ntlm_key *out)
{
- struct ntlm_buffer key = { key_exchange_key->data,
- key_exchange_key->length };
- struct ntlm_buffer nonce = { exported_session_key->data,
- exported_session_key->length };
- struct ntlm_buffer cipher = { encrypted_random_session_key->data,
- encrypted_random_session_key->length };
-
- return RC4K(&key, NTLM_CIPHER_ENCRYPT, &nonce, &cipher);
+ struct ntlm_buffer _key = { key->data, key->length };
+ struct ntlm_buffer data = { in->data, in->length };
+ struct ntlm_buffer result = { out->data, out->length };
+
+ return RC4K(&_key, NTLM_CIPHER_ENCRYPT, &data, &result);
}
static int ntlm_key_derivation_function(struct ntlm_key *key,
@@ -557,3 +553,69 @@ int ntlm_signseal_keys(uint32_t flags, bool client,
return 0;
}
+
+int ntlmv2_verify_nt_response(struct ntlm_buffer *nt_response,
+ struct ntlm_key *ntlmv2_key,
+ uint8_t server_chal[8])
+{
+ union wire_ntlm_response *nt_resp = NULL;
+ struct ntlm_buffer key = { ntlmv2_key->data, ntlmv2_key->length };
+ uint8_t proof[16];
+ struct ntlm_buffer nt_proof = { proof, 16 };
+ struct ntlm_buffer payload;
+ int ret;
+
+ if (nt_response->length < 24) return EINVAL;
+
+ nt_resp = (union wire_ntlm_response *)nt_response->data;
+
+ payload.length = 8;
+ payload.data = server_chal;
+
+ payload.length = nt_response->length - 8;
+ payload.data = malloc(payload.length);
+ if (!payload.data) return ENOMEM;
+ memcpy(payload.data, server_chal, 8);
+ memcpy(&payload.data[8], nt_resp->v2.cli_chal, payload.length - 8);
+
+ ret = HMAC_MD5(&key, &payload, &nt_proof);
+
+ if (ret) goto done;
+
+ ret = EINVAL;
+ if (memcmp(nt_resp->v2.resp, proof, 16) == 0) {
+ ret = 0;
+ }
+
+done:
+ safefree(payload.data);
+ return ret;
+}
+
+int ntlmv2_verify_lm_response(struct ntlm_buffer *lm_response,
+ struct ntlm_key *ntlmv2_key,
+ uint8_t server_chal[8])
+{
+ struct ntlm_buffer key = { ntlmv2_key->data, ntlmv2_key->length };
+ union wire_lm_response *lm_resp = NULL;
+ uint8_t payload_buf[16];
+ struct ntlm_buffer payload = { payload_buf, 16 };
+ uint8_t proof[16];
+ struct ntlm_buffer lm_proof = { proof, 16 };
+ int ret;
+
+ if (lm_response->length != 24) return EINVAL;
+
+ /* now caluclate the LM Proof */
+ lm_resp = (union wire_lm_response *)lm_response->data;
+
+ memcpy(payload.data, server_chal, 8);
+ memcpy(&payload.data[8], lm_resp->v2.cli_chal, 8);
+ ret = HMAC_MD5(&key, &payload, &lm_proof);
+
+ if (ret) return ret;
+
+ if (memcmp(lm_resp->v2.resp, proof, 16) == 0) return 0;
+
+ return EINVAL;
+}